1 /* $NetBSD: pm2fb.c,v 1.1 2009/10/28 02:10:27 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 Permedia 2 graphics controllers
30 * tested on sparc64 only so far
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.1 2009/10/28 02:10:27 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/pci/pm2reg.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>
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
;
85 u_char sc_cmap_red
[256];
86 u_char sc_cmap_green
[256];
87 u_char sc_cmap_blue
[256];
89 uint32_t sc_master_cntl
;
92 static int pm2fb_match(device_t
, cfdata_t
, void *);
93 static void pm2fb_attach(device_t
, device_t
, void *);
95 CFATTACH_DECL_NEW(pm2fb
, sizeof(struct pm2fb_softc
),
96 pm2fb_match
, pm2fb_attach
, NULL
, NULL
);
98 extern const u_char rasops_cmap
[768];
100 static int pm2fb_ioctl(void *, void *, u_long
, void *, int,
102 static paddr_t
pm2fb_mmap(void *, void *, off_t
, int);
103 static void pm2fb_init_screen(void *, struct vcons_screen
*, int, long *);
105 static int pm2fb_putcmap(struct pm2fb_softc
*, struct wsdisplay_cmap
*);
106 static int pm2fb_getcmap(struct pm2fb_softc
*, struct wsdisplay_cmap
*);
107 static void pm2fb_restore_palette(struct pm2fb_softc
*);
108 static int pm2fb_putpalreg(struct pm2fb_softc
*, uint8_t, uint8_t,
111 static void pm2fb_init(struct pm2fb_softc
*);
112 static void pm2fb_flush_engine(struct pm2fb_softc
*);
113 static void pm2fb_rectfill(struct pm2fb_softc
*, int, int, int, int,
115 static void pm2fb_bitblt(struct pm2fb_softc
*, int, int, int, int, int,
118 static void pm2fb_cursor(void *, int, int, int);
120 static void pm2fb_putchar(void *, int, int, u_int
, long);
122 static void pm2fb_copycols(void *, int, int, int, int);
123 static void pm2fb_erasecols(void *, int, int, int, long);
124 static void pm2fb_copyrows(void *, int, int, int);
125 static void pm2fb_eraserows(void *, int, int, long);
127 struct wsdisplay_accessops pm2fb_accessops
= {
130 NULL
, /* alloc_screen */
131 NULL
, /* free_screen */
132 NULL
, /* show_screen */
133 NULL
, /* load_font */
139 pm2fb_wait(struct pm2fb_softc
*sc
, int slots
)
144 reg
= bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
145 PM2_INPUT_FIFO_SPACE
);
146 } while (reg
<= slots
);
150 pm2fb_flush_engine(struct pm2fb_softc
*sc
)
155 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_FILTER_MODE
,
157 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_SYNC
, 0);
159 while (bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
160 PM2_OUTPUT_FIFO_WORDS
) == 0);
161 } while (bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
, PM2_OUTPUT_FIFO
) !=
166 pm2fb_match(device_t parent
, cfdata_t match
, void *aux
)
168 struct pci_attach_args
*pa
= (struct pci_attach_args
*)aux
;
170 if (PCI_CLASS(pa
->pa_class
) != PCI_CLASS_DISPLAY
)
172 if (PCI_VENDOR(pa
->pa_id
) != PCI_VENDOR_3DLABS
)
175 /* only cards tested on so far - likely need a list */
176 if ((PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_3DLABS_PERMEDIA2
) ||
177 (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_3DLABS_PERMEDIA2V
))
183 pm2fb_attach(device_t parent
, device_t self
, void *aux
)
185 struct pm2fb_softc
*sc
= device_private(self
);
186 struct pci_attach_args
*pa
= aux
;
187 struct rasops_info
*ri
;
189 struct wsemuldisplaydev_attach_args aa
;
190 prop_dictionary_t dict
;
191 unsigned long defattr
;
195 sc
->sc_pc
= pa
->pa_pc
;
196 sc
->sc_pcitag
= pa
->pa_tag
;
197 sc
->sc_memt
= pa
->pa_memt
;
198 sc
->sc_iot
= pa
->pa_iot
;
201 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
202 aprint_normal(": %s\n", devinfo
);
204 /* fill in parameters from properties */
205 dict
= device_properties(self
);
206 if (!prop_dictionary_get_uint32(dict
, "width", &sc
->sc_width
)) {
207 aprint_error("%s: no width property\n", device_xname(self
));
210 if (!prop_dictionary_get_uint32(dict
, "height", &sc
->sc_height
)) {
211 aprint_error("%s: no height property\n", device_xname(self
));
214 if (!prop_dictionary_get_uint32(dict
, "depth", &sc
->sc_depth
)) {
215 aprint_error("%s: no depth property\n", device_xname(self
));
219 * don't look at the linebytes property - The Raptor firmware lies
220 * about it. Get it from width * depth >> 3 instead.
222 sc
->sc_stride
= sc
->sc_width
* (sc
->sc_depth
>> 3);
224 prop_dictionary_get_bool(dict
, "is_console", &is_console
);
226 if (pci_mapreg_map(pa
, 0x14, PCI_MAPREG_TYPE_MEM
,
227 BUS_SPACE_MAP_LINEAR
,
228 &sc
->sc_memt
, &sc
->sc_fbh
, &sc
->sc_fb
, &sc
->sc_fbsize
)) {
229 aprint_error("%s: failed to map the frame buffer.\n",
230 device_xname(sc
->sc_dev
));
232 sc
->sc_fbaddr
= bus_space_vaddr(sc
->sc_memt
, sc
->sc_fbh
);
234 if (pci_mapreg_map(pa
, 0x10, PCI_MAPREG_TYPE_MEM
, 0,
235 &sc
->sc_memt
, &sc
->sc_regh
, &sc
->sc_reg
, &sc
->sc_regsize
)) {
236 aprint_error("%s: failed to map registers.\n",
237 device_xname(sc
->sc_dev
));
241 * XXX yeah, casting the fb address to uint32_t is formally wrong
242 * but as far as I know there are no PM2 with 64bit BARs
244 aprint_normal("%s: %d MB aperture at 0x%08x\n", device_xname(self
),
245 (int)(sc
->sc_fbsize
>> 20), (uint32_t)sc
->sc_fb
);
247 sc
->sc_defaultscreen_descr
= (struct wsscreen_descr
){
252 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
,
255 sc
->sc_screens
[0] = &sc
->sc_defaultscreen_descr
;
256 sc
->sc_screenlist
= (struct wsscreen_list
){1, sc
->sc_screens
};
257 sc
->sc_mode
= WSDISPLAYIO_MODE_EMUL
;
260 vcons_init(&sc
->vd
, sc
, &sc
->sc_defaultscreen_descr
,
262 sc
->vd
.init_screen
= pm2fb_init_screen
;
264 /* init engine here */
267 ri
= &sc
->sc_console_screen
.scr_ri
;
270 for (i
= 0; i
< (1 << sc
->sc_depth
); i
++) {
272 sc
->sc_cmap_red
[i
] = rasops_cmap
[j
];
273 sc
->sc_cmap_green
[i
] = rasops_cmap
[j
+ 1];
274 sc
->sc_cmap_blue
[i
] = rasops_cmap
[j
+ 2];
275 pm2fb_putpalreg(sc
, i
, rasops_cmap
[j
], rasops_cmap
[j
+ 1],
281 vcons_init_screen(&sc
->vd
, &sc
->sc_console_screen
, 1,
283 sc
->sc_console_screen
.scr_flags
|= VCONS_SCREEN_IS_STATIC
;
285 pm2fb_rectfill(sc
, 0, 0, sc
->sc_width
, sc
->sc_height
,
286 ri
->ri_devcmap
[(defattr
>> 16) & 0xff]);
287 sc
->sc_defaultscreen_descr
.textops
= &ri
->ri_ops
;
288 sc
->sc_defaultscreen_descr
.capabilities
= ri
->ri_caps
;
289 sc
->sc_defaultscreen_descr
.nrows
= ri
->ri_rows
;
290 sc
->sc_defaultscreen_descr
.ncols
= ri
->ri_cols
;
291 wsdisplay_cnattach(&sc
->sc_defaultscreen_descr
, ri
, 0, 0,
293 vcons_replay_msgbuf(&sc
->sc_console_screen
);
296 * since we're not the console we can postpone the rest
297 * until someone actually allocates a screen for us
299 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
302 aa
.console
= is_console
;
303 aa
.scrdata
= &sc
->sc_screenlist
;
304 aa
.accessops
= &pm2fb_accessops
;
305 aa
.accesscookie
= &sc
->vd
;
307 config_found(sc
->sc_dev
, &aa
, wsemuldisplaydevprint
);
309 printf("ap1 register: %08x\n", bus_space_read_4(sc
->sc_memt
,
310 sc
->sc_regh
, PM2_APERTURE1_CONTROL
));
315 pm2fb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
318 struct vcons_data
*vd
= v
;
319 struct pm2fb_softc
*sc
= vd
->cookie
;
320 struct wsdisplay_fbinfo
*wdf
;
321 struct vcons_screen
*ms
= vd
->active
;
325 case WSDISPLAYIO_GTYPE
:
326 *(u_int
*)data
= WSDISPLAY_TYPE_PCIMISC
;
329 /* PCI config read/write passthrough. */
330 case PCI_IOC_CFGREAD
:
331 case PCI_IOC_CFGWRITE
:
332 return (pci_devioctl(sc
->sc_pc
, sc
->sc_pcitag
,
333 cmd
, data
, flag
, l
));
335 case WSDISPLAYIO_GINFO
:
339 wdf
->height
= ms
->scr_ri
.ri_height
;
340 wdf
->width
= ms
->scr_ri
.ri_width
;
341 wdf
->depth
= ms
->scr_ri
.ri_depth
;
345 case WSDISPLAYIO_GETCMAP
:
346 return pm2fb_getcmap(sc
,
347 (struct wsdisplay_cmap
*)data
);
349 case WSDISPLAYIO_PUTCMAP
:
350 return pm2fb_putcmap(sc
,
351 (struct wsdisplay_cmap
*)data
);
353 case WSDISPLAYIO_LINEBYTES
:
354 *(u_int
*)data
= sc
->sc_stride
;
357 case WSDISPLAYIO_SMODE
:
359 int new_mode
= *(int*)data
;
361 /* notify the bus backend */
362 if (new_mode
!= sc
->sc_mode
) {
363 sc
->sc_mode
= new_mode
;
364 if(new_mode
== WSDISPLAYIO_MODE_EMUL
) {
365 pm2fb_restore_palette(sc
);
366 vcons_redraw_screen(ms
);
376 pm2fb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
378 struct vcons_data
*vd
= v
;
379 struct pm2fb_softc
*sc
= vd
->cookie
;
382 /* 'regular' framebuffer mmap()ing */
383 if (offset
< sc
->sc_fbsize
) {
384 pa
= bus_space_mmap(sc
->sc_memt
, sc
->sc_fb
+ offset
, 0, prot
,
385 BUS_SPACE_MAP_LINEAR
);
390 * restrict all other mappings to processes with superuser privileges
391 * or the kernel itself
393 if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER
,
395 aprint_normal("%s: mmap() rejected.\n",
396 device_xname(sc
->sc_dev
));
400 if ((offset
>= sc
->sc_fb
) && (offset
< (sc
->sc_fb
+ sc
->sc_fbsize
))) {
401 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
402 BUS_SPACE_MAP_LINEAR
);
406 if ((offset
>= sc
->sc_reg
) &&
407 (offset
< (sc
->sc_reg
+ sc
->sc_regsize
))) {
408 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
409 BUS_SPACE_MAP_LINEAR
);
413 #ifdef PCI_MAGIC_IO_RANGE
414 /* allow mapping of IO space */
415 if ((offset
>= PCI_MAGIC_IO_RANGE
) &&
416 (offset
< PCI_MAGIC_IO_RANGE
+ 0x10000)) {
417 pa
= bus_space_mmap(sc
->sc_iot
, offset
- PCI_MAGIC_IO_RANGE
,
418 0, prot
, BUS_SPACE_MAP_LINEAR
);
423 #ifdef OFB_ALLOW_OTHERS
424 if (offset
>= 0x80000000) {
425 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
426 BUS_SPACE_MAP_LINEAR
);
434 pm2fb_init_screen(void *cookie
, struct vcons_screen
*scr
,
435 int existing
, long *defattr
)
437 struct pm2fb_softc
*sc
= cookie
;
438 struct rasops_info
*ri
= &scr
->scr_ri
;
440 ri
->ri_depth
= sc
->sc_depth
;
441 ri
->ri_width
= sc
->sc_width
;
442 ri
->ri_height
= sc
->sc_height
;
443 ri
->ri_stride
= sc
->sc_stride
;
444 ri
->ri_flg
= RI_CENTER
| RI_FULLCLEAR
;
446 ri
->ri_bits
= (char *)sc
->sc_fbaddr
;
449 ri
->ri_flg
|= RI_CLEAR
;
452 rasops_init(ri
, sc
->sc_height
/ 8, sc
->sc_width
/ 8);
453 ri
->ri_caps
= WSSCREEN_WSCOLORS
;
455 rasops_reconfig(ri
, sc
->sc_height
/ ri
->ri_font
->fontheight
,
456 sc
->sc_width
/ ri
->ri_font
->fontwidth
);
459 ri
->ri_ops
.copyrows
= pm2fb_copyrows
;
460 ri
->ri_ops
.copycols
= pm2fb_copycols
;
461 ri
->ri_ops
.cursor
= pm2fb_cursor
;
462 ri
->ri_ops
.eraserows
= pm2fb_eraserows
;
463 ri
->ri_ops
.erasecols
= pm2fb_erasecols
;
465 ri
->ri_ops
.putchar
= pm2fb_putchar
;
470 pm2fb_putcmap(struct pm2fb_softc
*sc
, struct wsdisplay_cmap
*cm
)
473 u_int index
= cm
->index
;
474 u_int count
= cm
->count
;
476 u_char rbuf
[256], gbuf
[256], bbuf
[256];
479 aprint_debug("putcmap: %d %d\n",index
, count
);
481 if (cm
->index
>= 256 || cm
->count
> 256 ||
482 (cm
->index
+ cm
->count
) > 256)
484 error
= copyin(cm
->red
, &rbuf
[index
], count
);
487 error
= copyin(cm
->green
, &gbuf
[index
], count
);
490 error
= copyin(cm
->blue
, &bbuf
[index
], count
);
494 memcpy(&sc
->sc_cmap_red
[index
], &rbuf
[index
], count
);
495 memcpy(&sc
->sc_cmap_green
[index
], &gbuf
[index
], count
);
496 memcpy(&sc
->sc_cmap_blue
[index
], &bbuf
[index
], count
);
498 r
= &sc
->sc_cmap_red
[index
];
499 g
= &sc
->sc_cmap_green
[index
];
500 b
= &sc
->sc_cmap_blue
[index
];
502 for (i
= 0; i
< count
; i
++) {
503 pm2fb_putpalreg(sc
, index
, *r
, *g
, *b
);
511 pm2fb_getcmap(struct pm2fb_softc
*sc
, struct wsdisplay_cmap
*cm
)
513 u_int index
= cm
->index
;
514 u_int count
= cm
->count
;
517 if (index
>= 255 || count
> 256 || index
+ count
> 256)
520 error
= copyout(&sc
->sc_cmap_red
[index
], cm
->red
, count
);
523 error
= copyout(&sc
->sc_cmap_green
[index
], cm
->green
, count
);
526 error
= copyout(&sc
->sc_cmap_blue
[index
], cm
->blue
, count
);
534 pm2fb_restore_palette(struct pm2fb_softc
*sc
)
538 for (i
= 0; i
< (1 << sc
->sc_depth
); i
++) {
539 pm2fb_putpalreg(sc
, i
, sc
->sc_cmap_red
[i
],
540 sc
->sc_cmap_green
[i
], sc
->sc_cmap_blue
[i
]);
545 pm2fb_putpalreg(struct pm2fb_softc
*sc
, uint8_t idx
, uint8_t r
, uint8_t g
,
548 bus_space_write_1(sc
->sc_memt
, sc
->sc_regh
, PM2_DAC_PAL_WRITE_IDX
, idx
);
549 bus_space_write_1(sc
->sc_memt
, sc
->sc_regh
, PM2_DAC_DATA
, r
);
550 bus_space_write_1(sc
->sc_memt
, sc
->sc_regh
, PM2_DAC_DATA
, g
);
551 bus_space_write_1(sc
->sc_memt
, sc
->sc_regh
, PM2_DAC_DATA
, b
);
556 pm2fb_init(struct pm2fb_softc
*sc
)
561 pm2fb_flush_engine(sc
);
564 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_SCREEN_BASE
, 0);
566 switch (sc
->sc_depth
) {
568 datatype
= R128_GMC_DST_8BPP_CI
;
571 datatype
= R128_GMC_DST_15BPP
;
574 datatype
= R128_GMC_DST_16BPP
;
577 datatype
= R128_GMC_DST_24BPP
;
580 datatype
= R128_GMC_DST_32BPP
;
583 aprint_error("%s: unsupported depth %d\n",
584 device_xname(sc
->sc_dev
), sc
->sc_depth
);
587 sc
->sc_master_cntl
= R128_GMC_CLR_CMP_CNTL_DIS
|
588 R128_GMC_AUX_CLIP_DIS
| datatype
;
590 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_BYPASS_MASK
,
592 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_FB_WRITE_MASK
,
594 pm2fb_flush_engine(sc
);
598 pm2fb_rectfill(struct pm2fb_softc
*sc
, int x
, int y
, int wi
, int he
,
603 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_DDA_MODE
,
605 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_CONFIG
,
607 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_BLOCK_COLOUR
,
609 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_RECT_START
,
611 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_RECT_SIZE
,
613 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_RENDER
,
614 PM2RE_RECTANGLE
| PM2RE_INC_X
| PM2RE_INC_Y
| PM2RE_FASTFILL
);
616 pm2fb_flush_engine(sc
);
620 pm2fb_bitblt(struct pm2fb_softc
*sc
, int xs
, int ys
, int xd
, int yd
,
621 int wi
, int he
, int rop
)
632 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_DDA_MODE
, 0);
633 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_CONFIG
,
634 PM2RECFG_READ_SRC
| PM2RECFG_WRITE_EN
| PM2RECFG_ROP_EN
|
636 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_RECT_START
,
638 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_RECT_SIZE
,
640 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_SOURCE_DELTA
,
641 (((ys
- yd
) & 0xfff) << 16) | ((xs
- xd
) & 0xfff));
642 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, PM2_RE_RENDER
,
643 PM2RE_RECTANGLE
| dir
);
644 pm2fb_flush_engine(sc
);
648 pm2fb_cursor(void *cookie
, int on
, int row
, int col
)
650 struct rasops_info
*ri
= cookie
;
651 struct vcons_screen
*scr
= ri
->ri_hw
;
652 struct pm2fb_softc
*sc
= scr
->scr_cookie
;
655 wi
= ri
->ri_font
->fontwidth
;
656 he
= ri
->ri_font
->fontheight
;
658 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
659 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
660 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
661 if (ri
->ri_flg
& RI_CURSOR
) {
662 pm2fb_bitblt(sc
, x
, y
, x
, y
, wi
, he
, 12);
663 ri
->ri_flg
&= ~RI_CURSOR
;
668 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
669 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
670 pm2fb_bitblt(sc
, x
, y
, x
, y
, wi
, he
, 12);
671 ri
->ri_flg
|= RI_CURSOR
;
674 scr
->scr_ri
.ri_crow
= row
;
675 scr
->scr_ri
.ri_ccol
= col
;
676 scr
->scr_ri
.ri_flg
&= ~RI_CURSOR
;
683 pm2fb_putchar(void *cookie
, int row
, int col
, u_int c
, long attr
)
689 pm2fb_copycols(void *cookie
, int row
, int srccol
, int dstcol
, int ncols
)
691 struct rasops_info
*ri
= cookie
;
692 struct vcons_screen
*scr
= ri
->ri_hw
;
693 struct pm2fb_softc
*sc
= scr
->scr_cookie
;
694 int32_t xs
, xd
, y
, width
, height
;
696 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
697 xs
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* srccol
;
698 xd
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* dstcol
;
699 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
700 width
= ri
->ri_font
->fontwidth
* ncols
;
701 height
= ri
->ri_font
->fontheight
;
702 pm2fb_bitblt(sc
, xs
, y
, xd
, y
, width
, height
, 3);
707 pm2fb_erasecols(void *cookie
, int row
, int startcol
, int ncols
, long fillattr
)
709 struct rasops_info
*ri
= cookie
;
710 struct vcons_screen
*scr
= ri
->ri_hw
;
711 struct pm2fb_softc
*sc
= scr
->scr_cookie
;
712 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
714 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
715 x
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* startcol
;
716 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
717 width
= ri
->ri_font
->fontwidth
* ncols
;
718 height
= ri
->ri_font
->fontheight
;
719 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
721 pm2fb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);
726 pm2fb_copyrows(void *cookie
, int srcrow
, int dstrow
, int nrows
)
728 struct rasops_info
*ri
= cookie
;
729 struct vcons_screen
*scr
= ri
->ri_hw
;
730 struct pm2fb_softc
*sc
= scr
->scr_cookie
;
731 int32_t x
, ys
, yd
, width
, height
;
733 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
735 ys
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* srcrow
;
736 yd
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* dstrow
;
737 width
= ri
->ri_emuwidth
;
738 height
= ri
->ri_font
->fontheight
*nrows
;
739 pm2fb_bitblt(sc
, x
, ys
, x
, yd
, width
, height
, 3);
744 pm2fb_eraserows(void *cookie
, int row
, int nrows
, long fillattr
)
746 struct rasops_info
*ri
= cookie
;
747 struct vcons_screen
*scr
= ri
->ri_hw
;
748 struct pm2fb_softc
*sc
= scr
->scr_cookie
;
749 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
751 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
753 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
754 width
= ri
->ri_emuwidth
;
755 height
= ri
->ri_font
->fontheight
* nrows
;
756 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
758 pm2fb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);