1 /* $NetBSD: r128fb.c,v 1.9 2009/08/20 02:40:57 macallan Exp $ */
4 * Copyright (c) 2007 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 ATI Rage 128 graphics controllers
30 * tested on macppc only so far
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.9 2009/08/20 02:40:57 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/r128fbreg.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 r128fb_match(device_t
, cfdata_t
, void *);
93 static void r128fb_attach(device_t
, device_t
, void *);
95 CFATTACH_DECL_NEW(r128fb
, sizeof(struct r128fb_softc
),
96 r128fb_match
, r128fb_attach
, NULL
, NULL
);
98 extern const u_char rasops_cmap
[768];
100 static int r128fb_ioctl(void *, void *, u_long
, void *, int,
102 static paddr_t
r128fb_mmap(void *, void *, off_t
, int);
103 static void r128fb_init_screen(void *, struct vcons_screen
*, int, long *);
105 static int r128fb_putcmap(struct r128fb_softc
*, struct wsdisplay_cmap
*);
106 static int r128fb_getcmap(struct r128fb_softc
*, struct wsdisplay_cmap
*);
107 static void r128fb_restore_palette(struct r128fb_softc
*);
108 static int r128fb_putpalreg(struct r128fb_softc
*, uint8_t, uint8_t,
111 static void r128fb_init(struct r128fb_softc
*);
112 static void r128fb_flush_engine(struct r128fb_softc
*);
113 static void r128fb_rectfill(struct r128fb_softc
*, int, int, int, int,
115 static void r128fb_bitblt(struct r128fb_softc
*, int, int, int, int, int,
118 static void r128fb_cursor(void *, int, int, int);
120 static void r128fb_putchar(void *, int, int, u_int
, long);
122 static void r128fb_copycols(void *, int, int, int, int);
123 static void r128fb_erasecols(void *, int, int, int, long);
124 static void r128fb_copyrows(void *, int, int, int);
125 static void r128fb_eraserows(void *, int, int, long);
127 struct wsdisplay_accessops r128fb_accessops
= {
130 NULL
, /* alloc_screen */
131 NULL
, /* free_screen */
132 NULL
, /* show_screen */
133 NULL
, /* load_font */
139 r128fb_wait(struct r128fb_softc
*sc
, int slots
)
144 reg
= (bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
145 R128_GUI_STAT
) & R128_GUI_FIFOCNT_MASK
);
146 } while (reg
<= slots
);
150 r128fb_flush_engine(struct r128fb_softc
*sc
)
154 reg
= bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
, R128_PC_NGUI_CTLSTAT
);
155 reg
|= R128_PC_FLUSH_ALL
;
156 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_PC_NGUI_CTLSTAT
, reg
);
158 reg
= bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
159 R128_PC_NGUI_CTLSTAT
);
160 } while (reg
& R128_PC_BUSY
);
164 r128fb_match(device_t parent
, cfdata_t match
, void *aux
)
166 struct pci_attach_args
*pa
= (struct pci_attach_args
*)aux
;
168 if (PCI_CLASS(pa
->pa_class
) != PCI_CLASS_DISPLAY
)
170 if (PCI_VENDOR(pa
->pa_id
) != PCI_VENDOR_ATI
)
173 /* only cards tested on so far - likely need a list */
174 if ((PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_ATI_RAGE1AGP4XT
) ||
175 (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_ATI_RAGE3AGP4XT
) ||
176 (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_ATI_RAGEGLPCI
) ||
177 (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP
))
183 r128fb_attach(device_t parent
, device_t self
, void *aux
)
185 struct r128fb_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
));
218 if (!prop_dictionary_get_uint32(dict
, "linebytes", &sc
->sc_stride
)) {
219 aprint_error("%s: no linebytes property\n",
224 prop_dictionary_get_bool(dict
, "is_console", &is_console
);
226 if (pci_mapreg_map(pa
, 0x10, 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
, 0x18, 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 mach64 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
= r128fb_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 r128fb_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 r128fb_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
= &r128fb_accessops
;
305 aa
.accesscookie
= &sc
->vd
;
307 config_found(sc
->sc_dev
, &aa
, wsemuldisplaydevprint
);
312 r128fb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
315 struct vcons_data
*vd
= v
;
316 struct r128fb_softc
*sc
= vd
->cookie
;
317 struct wsdisplay_fbinfo
*wdf
;
318 struct vcons_screen
*ms
= vd
->active
;
322 case WSDISPLAYIO_GTYPE
:
323 *(u_int
*)data
= WSDISPLAY_TYPE_PCIMISC
;
326 /* PCI config read/write passthrough. */
327 case PCI_IOC_CFGREAD
:
328 case PCI_IOC_CFGWRITE
:
329 return (pci_devioctl(sc
->sc_pc
, sc
->sc_pcitag
,
330 cmd
, data
, flag
, l
));
332 case WSDISPLAYIO_GINFO
:
336 wdf
->height
= ms
->scr_ri
.ri_height
;
337 wdf
->width
= ms
->scr_ri
.ri_width
;
338 wdf
->depth
= ms
->scr_ri
.ri_depth
;
342 case WSDISPLAYIO_GETCMAP
:
343 return r128fb_getcmap(sc
,
344 (struct wsdisplay_cmap
*)data
);
346 case WSDISPLAYIO_PUTCMAP
:
347 return r128fb_putcmap(sc
,
348 (struct wsdisplay_cmap
*)data
);
350 case WSDISPLAYIO_LINEBYTES
:
351 *(u_int
*)data
= sc
->sc_stride
;
354 case WSDISPLAYIO_SMODE
:
356 int new_mode
= *(int*)data
;
358 /* notify the bus backend */
359 if (new_mode
!= sc
->sc_mode
) {
360 sc
->sc_mode
= new_mode
;
361 if(new_mode
== WSDISPLAYIO_MODE_EMUL
) {
362 r128fb_restore_palette(sc
);
363 vcons_redraw_screen(ms
);
373 r128fb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
375 struct vcons_data
*vd
= v
;
376 struct r128fb_softc
*sc
= vd
->cookie
;
379 /* 'regular' framebuffer mmap()ing */
380 if (offset
< sc
->sc_fbsize
) {
381 pa
= bus_space_mmap(sc
->sc_memt
, sc
->sc_fb
+ offset
, 0, prot
,
382 BUS_SPACE_MAP_LINEAR
);
387 * restrict all other mappings to processes with superuser privileges
388 * or the kernel itself
390 if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER
,
392 aprint_normal("%s: mmap() rejected.\n",
393 device_xname(sc
->sc_dev
));
397 if ((offset
>= sc
->sc_fb
) && (offset
< (sc
->sc_fb
+ sc
->sc_fbsize
))) {
398 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
399 BUS_SPACE_MAP_LINEAR
);
403 if ((offset
>= sc
->sc_reg
) &&
404 (offset
< (sc
->sc_reg
+ sc
->sc_regsize
))) {
405 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
406 BUS_SPACE_MAP_LINEAR
);
410 #ifdef PCI_MAGIC_IO_RANGE
411 /* allow mapping of IO space */
412 if ((offset
>= PCI_MAGIC_IO_RANGE
) &&
413 (offset
< PCI_MAGIC_IO_RANGE
+ 0x10000)) {
414 pa
= bus_space_mmap(sc
->sc_iot
, offset
- PCI_MAGIC_IO_RANGE
,
415 0, prot
, BUS_SPACE_MAP_LINEAR
);
420 #ifdef OFB_ALLOW_OTHERS
421 if (offset
>= 0x80000000) {
422 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
423 BUS_SPACE_MAP_LINEAR
);
431 r128fb_init_screen(void *cookie
, struct vcons_screen
*scr
,
432 int existing
, long *defattr
)
434 struct r128fb_softc
*sc
= cookie
;
435 struct rasops_info
*ri
= &scr
->scr_ri
;
437 ri
->ri_depth
= sc
->sc_depth
;
438 ri
->ri_width
= sc
->sc_width
;
439 ri
->ri_height
= sc
->sc_height
;
440 ri
->ri_stride
= sc
->sc_stride
;
441 ri
->ri_flg
= RI_CENTER
| RI_FULLCLEAR
;
443 ri
->ri_bits
= (char *)sc
->sc_fbaddr
;
446 ri
->ri_flg
|= RI_CLEAR
;
449 rasops_init(ri
, sc
->sc_height
/ 8, sc
->sc_width
/ 8);
450 ri
->ri_caps
= WSSCREEN_WSCOLORS
;
452 rasops_reconfig(ri
, sc
->sc_height
/ ri
->ri_font
->fontheight
,
453 sc
->sc_width
/ ri
->ri_font
->fontwidth
);
456 ri
->ri_ops
.copyrows
= r128fb_copyrows
;
457 ri
->ri_ops
.copycols
= r128fb_copycols
;
458 ri
->ri_ops
.eraserows
= r128fb_eraserows
;
459 ri
->ri_ops
.erasecols
= r128fb_erasecols
;
460 ri
->ri_ops
.cursor
= r128fb_cursor
;
462 ri
->ri_ops
.putchar
= r128fb_putchar
;
467 r128fb_putcmap(struct r128fb_softc
*sc
, struct wsdisplay_cmap
*cm
)
470 u_int index
= cm
->index
;
471 u_int count
= cm
->count
;
473 u_char rbuf
[256], gbuf
[256], bbuf
[256];
476 aprint_debug("putcmap: %d %d\n",index
, count
);
478 if (cm
->index
>= 256 || cm
->count
> 256 ||
479 (cm
->index
+ cm
->count
) > 256)
481 error
= copyin(cm
->red
, &rbuf
[index
], count
);
484 error
= copyin(cm
->green
, &gbuf
[index
], count
);
487 error
= copyin(cm
->blue
, &bbuf
[index
], count
);
491 memcpy(&sc
->sc_cmap_red
[index
], &rbuf
[index
], count
);
492 memcpy(&sc
->sc_cmap_green
[index
], &gbuf
[index
], count
);
493 memcpy(&sc
->sc_cmap_blue
[index
], &bbuf
[index
], count
);
495 r
= &sc
->sc_cmap_red
[index
];
496 g
= &sc
->sc_cmap_green
[index
];
497 b
= &sc
->sc_cmap_blue
[index
];
499 for (i
= 0; i
< count
; i
++) {
500 r128fb_putpalreg(sc
, index
, *r
, *g
, *b
);
508 r128fb_getcmap(struct r128fb_softc
*sc
, struct wsdisplay_cmap
*cm
)
510 u_int index
= cm
->index
;
511 u_int count
= cm
->count
;
514 if (index
>= 255 || count
> 256 || index
+ count
> 256)
517 error
= copyout(&sc
->sc_cmap_red
[index
], cm
->red
, count
);
520 error
= copyout(&sc
->sc_cmap_green
[index
], cm
->green
, count
);
523 error
= copyout(&sc
->sc_cmap_blue
[index
], cm
->blue
, count
);
531 r128fb_restore_palette(struct r128fb_softc
*sc
)
535 for (i
= 0; i
< (1 << sc
->sc_depth
); i
++) {
536 r128fb_putpalreg(sc
, i
, sc
->sc_cmap_red
[i
],
537 sc
->sc_cmap_green
[i
], sc
->sc_cmap_blue
[i
]);
542 r128fb_putpalreg(struct r128fb_softc
*sc
, uint8_t idx
, uint8_t r
, uint8_t g
,
548 reg
= (r
<< 16) | (g
<< 8) | b
;
549 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_PALETTE_INDEX
, idx
);
550 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_PALETTE_DATA
, reg
);
555 r128fb_init(struct r128fb_softc
*sc
)
559 r128fb_flush_engine(sc
);
562 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_CRTC_OFFSET
, 0);
563 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DEFAULT_OFFSET
, 0);
564 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DEFAULT_PITCH
,
566 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_AUX_SC_CNTL
, 0);
567 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
568 R128_DEFAULT_SC_BOTTOM_RIGHT
,
569 R128_DEFAULT_SC_RIGHT_MAX
| R128_DEFAULT_SC_BOTTOM_MAX
);
570 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_SC_TOP_LEFT
, 0);
571 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_SC_BOTTOM_RIGHT
,
572 R128_DEFAULT_SC_RIGHT_MAX
| R128_DEFAULT_SC_BOTTOM_MAX
);
573 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_DATATYPE
,
574 R128_HOST_BIG_ENDIAN_EN
);
577 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_SRC_PITCH
,
579 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DST_PITCH
,
581 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_SRC_OFFSET
, 0);
582 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DST_OFFSET
, 0);
583 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_WRITE_MASK
,
586 switch (sc
->sc_depth
) {
588 datatype
= R128_GMC_DST_8BPP_CI
;
591 datatype
= R128_GMC_DST_15BPP
;
594 datatype
= R128_GMC_DST_16BPP
;
597 datatype
= R128_GMC_DST_24BPP
;
600 datatype
= R128_GMC_DST_32BPP
;
603 aprint_error("%s: unsupported depth %d\n",
604 device_xname(sc
->sc_dev
), sc
->sc_depth
);
607 sc
->sc_master_cntl
= R128_GMC_CLR_CMP_CNTL_DIS
|
608 R128_GMC_AUX_CLIP_DIS
| datatype
;
610 r128fb_flush_engine(sc
);
614 r128fb_rectfill(struct r128fb_softc
*sc
, int x
, int y
, int wi
, int he
,
619 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_GUI_MASTER_CNTL
,
620 R128_GMC_BRUSH_SOLID_COLOR
|
621 R128_GMC_SRC_DATATYPE_COLOR
|
625 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_BRUSH_FRGD_CLR
,
627 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_CNTL
,
628 R128_DST_X_LEFT_TO_RIGHT
| R128_DST_Y_TOP_TO_BOTTOM
);
629 /* now feed it coordinates */
630 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DST_X_Y
,
632 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DST_WIDTH_HEIGHT
,
634 r128fb_flush_engine(sc
);
638 r128fb_bitblt(struct r128fb_softc
*sc
, int xs
, int ys
, int xd
, int yd
,
639 int wi
, int he
, int rop
)
641 uint32_t dp_cntl
= 0;
644 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_GUI_MASTER_CNTL
,
645 R128_GMC_BRUSH_SOLID_COLOR
|
646 R128_GMC_SRC_DATATYPE_COLOR
|
648 R128_DP_SRC_SOURCE_MEMORY
|
652 dp_cntl
= R128_DST_Y_TOP_TO_BOTTOM
;
658 dp_cntl
|= R128_DST_X_LEFT_TO_RIGHT
;
663 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DP_CNTL
, dp_cntl
);
665 /* now feed it coordinates */
666 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_SRC_X_Y
,
668 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DST_X_Y
,
670 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, R128_DST_WIDTH_HEIGHT
,
672 r128fb_flush_engine(sc
);
676 r128fb_cursor(void *cookie
, int on
, int row
, int col
)
678 struct rasops_info
*ri
= cookie
;
679 struct vcons_screen
*scr
= ri
->ri_hw
;
680 struct r128fb_softc
*sc
= scr
->scr_cookie
;
683 wi
= ri
->ri_font
->fontwidth
;
684 he
= ri
->ri_font
->fontheight
;
686 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
687 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
688 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
689 if (ri
->ri_flg
& RI_CURSOR
) {
690 r128fb_bitblt(sc
, x
, y
, x
, y
, wi
, he
, R128_ROP3_Dn
);
691 ri
->ri_flg
&= ~RI_CURSOR
;
696 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
697 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
698 r128fb_bitblt(sc
, x
, y
, x
, y
, wi
, he
, R128_ROP3_Dn
);
699 ri
->ri_flg
|= RI_CURSOR
;
702 scr
->scr_ri
.ri_crow
= row
;
703 scr
->scr_ri
.ri_ccol
= col
;
704 scr
->scr_ri
.ri_flg
&= ~RI_CURSOR
;
711 r128fb_putchar(void *cookie
, int row
, int col
, u_int c
, long attr
)
717 r128fb_copycols(void *cookie
, int row
, int srccol
, int dstcol
, int ncols
)
719 struct rasops_info
*ri
= cookie
;
720 struct vcons_screen
*scr
= ri
->ri_hw
;
721 struct r128fb_softc
*sc
= scr
->scr_cookie
;
722 int32_t xs
, xd
, y
, width
, height
;
724 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
725 xs
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* srccol
;
726 xd
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* dstcol
;
727 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
728 width
= ri
->ri_font
->fontwidth
* ncols
;
729 height
= ri
->ri_font
->fontheight
;
730 r128fb_bitblt(sc
, xs
, y
, xd
, y
, width
, height
, R128_ROP3_S
);
735 r128fb_erasecols(void *cookie
, int row
, int startcol
, int ncols
, long fillattr
)
737 struct rasops_info
*ri
= cookie
;
738 struct vcons_screen
*scr
= ri
->ri_hw
;
739 struct r128fb_softc
*sc
= scr
->scr_cookie
;
740 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
742 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
743 x
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* startcol
;
744 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
745 width
= ri
->ri_font
->fontwidth
* ncols
;
746 height
= ri
->ri_font
->fontheight
;
747 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
749 r128fb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);
754 r128fb_copyrows(void *cookie
, int srcrow
, int dstrow
, int nrows
)
756 struct rasops_info
*ri
= cookie
;
757 struct vcons_screen
*scr
= ri
->ri_hw
;
758 struct r128fb_softc
*sc
= scr
->scr_cookie
;
759 int32_t x
, ys
, yd
, width
, height
;
761 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
763 ys
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* srcrow
;
764 yd
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* dstrow
;
765 width
= ri
->ri_emuwidth
;
766 height
= ri
->ri_font
->fontheight
*nrows
;
767 r128fb_bitblt(sc
, x
, ys
, x
, yd
, width
, height
, R128_ROP3_S
);
772 r128fb_eraserows(void *cookie
, int row
, int nrows
, long fillattr
)
774 struct rasops_info
*ri
= cookie
;
775 struct vcons_screen
*scr
= ri
->ri_hw
;
776 struct r128fb_softc
*sc
= scr
->scr_cookie
;
777 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
779 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
781 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
782 width
= ri
->ri_emuwidth
;
783 height
= ri
->ri_font
->fontheight
* nrows
;
784 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
786 r128fb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);