1 /* $NetBSD: cfb.c,v 1.56 2008/12/17 20:51:34 cegger Exp $ */
4 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: cfb.c,v 1.56 2008/12/17 20:51:34 cegger Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/device.h>
39 #include <sys/malloc.h>
41 #include <sys/ioctl.h>
46 #include <dev/wscons/wsconsio.h>
47 #include <dev/wscons/wsdisplayvar.h>
49 #include <dev/rasops/rasops.h>
50 #include <dev/wsfont/wsfont.h>
52 #include <dev/tc/tcvar.h>
53 #include <dev/ic/bt459reg.h>
55 #include <uvm/uvm_extern.h>
58 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
62 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
66 * N.B., Bt459 registers are 8bit width. Some of TC framebuffers have
67 * obscure register layout such as 2nd and 3rd Bt459 registers are
68 * adjacent each other in a word, i.e.,
69 * struct bt459triplet {
77 * Although CX has single Bt459, 32bit R/W can be done w/o any trouble.
86 /* Bt459 hardware registers, memory-mapped in 32bit stride */
92 #define REGWRITE32(p,i,v) do { \
93 *(volatile uint32_t *)((p) + (i)) = (v); tc_wmb(); \
95 #define VDACSELECT(p,r) do { \
96 REGWRITE32(p, bt_lo, 0xff & (r)); \
97 REGWRITE32(p, bt_hi, 0x0f & ((r)>>8)); \
101 #define CMAP_SIZE 256 /* 256 R/G/B entries */
102 uint8_t r
[CMAP_SIZE
];
103 uint8_t g
[CMAP_SIZE
];
104 uint8_t b
[CMAP_SIZE
];
108 struct wsdisplay_curpos cc_pos
;
109 struct wsdisplay_curpos cc_hot
;
110 struct wsdisplay_curpos cc_size
;
111 struct wsdisplay_curpos cc_magic
;
112 #define CURSOR_MAX_SIZE 64
114 uint64_t cc_image
[CURSOR_MAX_SIZE
];
115 uint64_t cc_mask
[CURSOR_MAX_SIZE
];
121 struct rasops_info
*sc_ri
;
122 struct hwcmap256 sc_cmap
; /* software copy of colormap */
123 struct hwcursor64 sc_cursor
; /* software copy of cursor */
125 int sc_curenb
; /* cursor sprite enabled */
126 int sc_changed
; /* need update of hardware */
127 #define WSDISPLAY_CMAP_DOLUT 0x20
131 #define CX_MAGIC_X 220
132 #define CX_MAGIC_Y 35
134 #define CX_FB_OFFSET 0x000000
135 #define CX_FB_SIZE 0x100000
136 #define CX_BT459_OFFSET 0x200000
137 #define CX_OFFSET_IREQ 0x300000 /* Interrupt req. control */
139 static int cfbmatch(device_t
, cfdata_t
, void *);
140 static void cfbattach(device_t
, device_t
, void *);
142 CFATTACH_DECL_NEW(cfb
, sizeof(struct cfb_softc
),
143 cfbmatch
, cfbattach
, NULL
, NULL
);
145 static void cfb_common_init(struct rasops_info
*);
146 static struct rasops_info cfb_console_ri
;
147 static tc_addr_t cfb_consaddr
;
149 static struct wsscreen_descr cfb_stdscreen
= {
156 static const struct wsscreen_descr
*_cfb_scrlist
[] = {
160 static const struct wsscreen_list cfb_screenlist
= {
161 sizeof(_cfb_scrlist
) / sizeof(struct wsscreen_descr
*), _cfb_scrlist
164 static int cfbioctl(void *, void *, u_long
, void *, int, struct lwp
*);
165 static paddr_t
cfbmmap(void *, void *, off_t
, int);
167 static int cfb_alloc_screen(void *, const struct wsscreen_descr
*,
168 void **, int *, int *, long *);
169 static void cfb_free_screen(void *, void *);
170 static int cfb_show_screen(void *, void *, int,
171 void (*) (void *, int, int), void *);
173 static const struct wsdisplay_accessops cfb_accessops
= {
182 int cfb_cnattach(tc_addr_t
);
183 static int cfbintr(void *);
184 static void cfbhwinit(void *);
185 static void cfb_cmap_init(struct cfb_softc
*);
187 static int get_cmap(struct cfb_softc
*, struct wsdisplay_cmap
*);
188 static int set_cmap(struct cfb_softc
*, struct wsdisplay_cmap
*);
189 static int set_cursor(struct cfb_softc
*, struct wsdisplay_cursor
*);
190 static int get_cursor(struct cfb_softc
*, struct wsdisplay_cursor
*);
191 static void set_curpos(struct cfb_softc
*, struct wsdisplay_curpos
*);
194 * Compose 2 bit/pixel cursor image. Bit order will be reversed.
195 * M M M M I I I I M I M I M I M I
196 * [ before ] [ after ]
197 * 3 2 1 0 3 2 1 0 0 0 1 1 2 2 3 3
198 * 7 6 5 4 7 6 5 4 4 4 5 5 6 6 7 7
200 static const uint8_t shuffle
[256] = {
201 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
202 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55,
203 0x80, 0xc0, 0x90, 0xd0, 0x84, 0xc4, 0x94, 0xd4,
204 0x81, 0xc1, 0x91, 0xd1, 0x85, 0xc5, 0x95, 0xd5,
205 0x20, 0x60, 0x30, 0x70, 0x24, 0x64, 0x34, 0x74,
206 0x21, 0x61, 0x31, 0x71, 0x25, 0x65, 0x35, 0x75,
207 0xa0, 0xe0, 0xb0, 0xf0, 0xa4, 0xe4, 0xb4, 0xf4,
208 0xa1, 0xe1, 0xb1, 0xf1, 0xa5, 0xe5, 0xb5, 0xf5,
209 0x08, 0x48, 0x18, 0x58, 0x0c, 0x4c, 0x1c, 0x5c,
210 0x09, 0x49, 0x19, 0x59, 0x0d, 0x4d, 0x1d, 0x5d,
211 0x88, 0xc8, 0x98, 0xd8, 0x8c, 0xcc, 0x9c, 0xdc,
212 0x89, 0xc9, 0x99, 0xd9, 0x8d, 0xcd, 0x9d, 0xdd,
213 0x28, 0x68, 0x38, 0x78, 0x2c, 0x6c, 0x3c, 0x7c,
214 0x29, 0x69, 0x39, 0x79, 0x2d, 0x6d, 0x3d, 0x7d,
215 0xa8, 0xe8, 0xb8, 0xf8, 0xac, 0xec, 0xbc, 0xfc,
216 0xa9, 0xe9, 0xb9, 0xf9, 0xad, 0xed, 0xbd, 0xfd,
217 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56,
218 0x03, 0x43, 0x13, 0x53, 0x07, 0x47, 0x17, 0x57,
219 0x82, 0xc2, 0x92, 0xd2, 0x86, 0xc6, 0x96, 0xd6,
220 0x83, 0xc3, 0x93, 0xd3, 0x87, 0xc7, 0x97, 0xd7,
221 0x22, 0x62, 0x32, 0x72, 0x26, 0x66, 0x36, 0x76,
222 0x23, 0x63, 0x33, 0x73, 0x27, 0x67, 0x37, 0x77,
223 0xa2, 0xe2, 0xb2, 0xf2, 0xa6, 0xe6, 0xb6, 0xf6,
224 0xa3, 0xe3, 0xb3, 0xf3, 0xa7, 0xe7, 0xb7, 0xf7,
225 0x0a, 0x4a, 0x1a, 0x5a, 0x0e, 0x4e, 0x1e, 0x5e,
226 0x0b, 0x4b, 0x1b, 0x5b, 0x0f, 0x4f, 0x1f, 0x5f,
227 0x8a, 0xca, 0x9a, 0xda, 0x8e, 0xce, 0x9e, 0xde,
228 0x8b, 0xcb, 0x9b, 0xdb, 0x8f, 0xcf, 0x9f, 0xdf,
229 0x2a, 0x6a, 0x3a, 0x7a, 0x2e, 0x6e, 0x3e, 0x7e,
230 0x2b, 0x6b, 0x3b, 0x7b, 0x2f, 0x6f, 0x3f, 0x7f,
231 0xaa, 0xea, 0xba, 0xfa, 0xae, 0xee, 0xbe, 0xfe,
232 0xab, 0xeb, 0xbb, 0xfb, 0xaf, 0xef, 0xbf, 0xff,
236 cfbmatch(device_t parent
, cfdata_t match
, void *aux
)
238 struct tc_attach_args
*ta
= aux
;
240 if (strncmp("PMAG-BA ", ta
->ta_modname
, TC_ROM_LLEN
) != 0)
247 cfbattach(device_t parent
, device_t self
, void *aux
)
249 struct cfb_softc
*sc
= device_private(self
);
250 struct tc_attach_args
*ta
= aux
;
251 struct rasops_info
*ri
;
252 struct wsemuldisplaydev_attach_args waa
;
255 console
= (ta
->ta_addr
== cfb_consaddr
);
257 sc
->sc_ri
= ri
= &cfb_console_ri
;
261 ri
= malloc(sizeof(struct rasops_info
),
262 M_DEVBUF
, M_NOWAIT
|M_ZERO
);
264 printf(": can't alloc memory\n");
268 ri
->ri_hw
= (void *)ta
->ta_addr
;
272 printf(": %dx%d, %dbpp\n", ri
->ri_width
, ri
->ri_height
, ri
->ri_depth
);
276 sc
->sc_vaddr
= ta
->ta_addr
;
277 sc
->sc_cursor
.cc_magic
.x
= CX_MAGIC_X
;
278 sc
->sc_cursor
.cc_magic
.y
= CX_MAGIC_Y
;
279 sc
->sc_blanked
= sc
->sc_curenb
= 0;
281 tc_intr_establish(parent
, ta
->ta_cookie
, IPL_TTY
, cfbintr
, sc
);
283 /* clear any pending interrupts */
284 *(volatile uint8_t *)((char *)ri
->ri_hw
+ CX_OFFSET_IREQ
) = 0;
286 waa
.console
= console
;
287 waa
.scrdata
= &cfb_screenlist
;
288 waa
.accessops
= &cfb_accessops
;
289 waa
.accesscookie
= sc
;
291 config_found(self
, &waa
, wsemuldisplaydevprint
);
295 cfb_cmap_init(struct cfb_softc
*sc
)
297 struct hwcmap256
*cm
;
303 for (index
= 0; index
< CMAP_SIZE
; index
++, p
+= 3) {
311 cfb_common_init(struct rasops_info
*ri
)
316 base
= (void *)ri
->ri_hw
;
318 /* initialize colormap and cursor hardware */
321 ri
->ri_flg
= RI_CENTER
;
325 ri
->ri_stride
= 1024;
326 ri
->ri_bits
= base
+ CX_FB_OFFSET
;
328 /* clear the screen */
329 memset(ri
->ri_bits
, 0, ri
->ri_stride
* ri
->ri_height
);
332 /* prefer 12 pixel wide font */
333 cookie
= wsfont_find(NULL
, 12, 0, 0, WSDISPLAY_FONTORDER_L2R
,
334 WSDISPLAY_FONTORDER_L2R
);
336 cookie
= wsfont_find(NULL
, 0, 0, 0, WSDISPLAY_FONTORDER_L2R
,
337 WSDISPLAY_FONTORDER_L2R
);
339 printf("cfb: font table is empty\n");
343 if (wsfont_lock(cookie
, &ri
->ri_font
)) {
344 printf("cfb: couldn't lock font\n");
347 ri
->ri_wsfcookie
= cookie
;
349 rasops_init(ri
, 34, 80);
351 /* XXX shouldn't be global */
352 cfb_stdscreen
.nrows
= ri
->ri_rows
;
353 cfb_stdscreen
.ncols
= ri
->ri_cols
;
354 cfb_stdscreen
.textops
= &ri
->ri_ops
;
355 cfb_stdscreen
.capabilities
= ri
->ri_caps
;
359 cfbioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
361 struct cfb_softc
*sc
= v
;
362 struct rasops_info
*ri
= sc
->sc_ri
;
366 case WSDISPLAYIO_GTYPE
:
367 *(u_int
*)data
= WSDISPLAY_TYPE_CFB
;
370 case WSDISPLAYIO_GINFO
:
371 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
372 wsd_fbip
->height
= ri
->ri_height
;
373 wsd_fbip
->width
= ri
->ri_width
;
374 wsd_fbip
->depth
= ri
->ri_depth
;
375 wsd_fbip
->cmsize
= CMAP_SIZE
;
379 case WSDISPLAYIO_GETCMAP
:
380 return get_cmap(sc
, (struct wsdisplay_cmap
*)data
);
382 case WSDISPLAYIO_PUTCMAP
:
383 return set_cmap(sc
, (struct wsdisplay_cmap
*)data
);
385 case WSDISPLAYIO_SVIDEO
:
386 turnoff
= *(int *)data
== WSDISPLAYIO_VIDEO_OFF
;
387 if (sc
->sc_blanked
!= turnoff
) {
388 sc
->sc_blanked
= turnoff
;
393 case WSDISPLAYIO_GVIDEO
:
394 *(u_int
*)data
= sc
->sc_blanked
?
395 WSDISPLAYIO_VIDEO_OFF
: WSDISPLAYIO_VIDEO_ON
;
398 case WSDISPLAYIO_GCURPOS
:
399 *(struct wsdisplay_curpos
*)data
= sc
->sc_cursor
.cc_pos
;
402 case WSDISPLAYIO_SCURPOS
:
404 set_curpos(sc
, (struct wsdisplay_curpos
*)data
);
405 sc
->sc_changed
|= WSDISPLAY_CURSOR_DOPOS
;
409 case WSDISPLAYIO_GCURMAX
:
410 ((struct wsdisplay_curpos
*)data
)->x
=
411 ((struct wsdisplay_curpos
*)data
)->y
= CURSOR_MAX_SIZE
;
414 case WSDISPLAYIO_GCURSOR
:
415 return get_cursor(sc
, (struct wsdisplay_cursor
*)data
);
417 case WSDISPLAYIO_SCURSOR
:
418 return set_cursor(sc
, (struct wsdisplay_cursor
*)data
);
420 case WSDISPLAYIO_SMODE
:
421 if (*(int *)data
== WSDISPLAYIO_MODE_EMUL
) {
426 sc
->sc_changed
|= (WSDISPLAY_CURSOR_DOCUR
|
427 WSDISPLAY_CMAP_DOLUT
);
436 cfbmmap(void *v
, void *vs
, off_t offset
, int prot
)
438 struct cfb_softc
*sc
= v
;
440 if (offset
>= CX_FB_SIZE
|| offset
< 0)
442 return machine_btop(sc
->sc_vaddr
+ CX_FB_OFFSET
+ offset
);
446 cfb_alloc_screen(void *v
, const struct wsscreen_descr
*type
, void **cookiep
,
447 int *curxp
, int *curyp
, long *attrp
)
449 struct cfb_softc
*sc
= v
;
450 struct rasops_info
*ri
= sc
->sc_ri
;
453 if (sc
->nscreens
> 0)
456 *cookiep
= ri
; /* one and only for now */
459 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
466 cfb_free_screen(void *v
, void *cookie
)
468 struct cfb_softc
*sc
= v
;
470 if (sc
->sc_ri
== &cfb_console_ri
)
471 panic("cfb_free_screen: console");
477 cfb_show_screen(void *v
, void *cookie
, int waitok
,
478 void (*cb
)(void *, int, int), void *cbarg
)
485 cfb_cnattach(tc_addr_t addr
)
487 struct rasops_info
*ri
;
490 ri
= &cfb_console_ri
;
491 ri
->ri_hw
= (void *)addr
;
493 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
494 wsdisplay_cnattach(&cfb_stdscreen
, ri
, 0, 0, defattr
);
502 struct cfb_softc
*sc
= arg
;
506 base
= (void *)sc
->sc_ri
->ri_hw
;
507 *(uint8_t *)(base
+ CX_OFFSET_IREQ
) = 0;
508 if (sc
->sc_changed
== 0)
511 vdac
= base
+ CX_BT459_OFFSET
;
513 if (v
& WSDISPLAY_CURSOR_DOCUR
) {
514 VDACSELECT(vdac
, BT459_IREG_CCR
);
515 REGWRITE32(vdac
, bt_reg
, (sc
->sc_curenb
) ? 0xc0 : 0x00);
517 if (v
& (WSDISPLAY_CURSOR_DOPOS
| WSDISPLAY_CURSOR_DOHOT
)) {
520 x
= sc
->sc_cursor
.cc_pos
.x
- sc
->sc_cursor
.cc_hot
.x
;
521 y
= sc
->sc_cursor
.cc_pos
.y
- sc
->sc_cursor
.cc_hot
.y
;
523 x
+= sc
->sc_cursor
.cc_magic
.x
;
524 y
+= sc
->sc_cursor
.cc_magic
.y
;
526 VDACSELECT(vdac
, BT459_IREG_CURSOR_X_LOW
);
527 REGWRITE32(vdac
, bt_reg
, x
);
528 REGWRITE32(vdac
, bt_reg
, x
>> 8);
529 REGWRITE32(vdac
, bt_reg
, y
);
530 REGWRITE32(vdac
, bt_reg
, y
>> 8);
532 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
533 uint8_t *cp
= sc
->sc_cursor
.cc_color
;
535 VDACSELECT(vdac
, BT459_IREG_CCOLOR_2
);
536 REGWRITE32(vdac
, bt_reg
, cp
[1]);
537 REGWRITE32(vdac
, bt_reg
, cp
[3]);
538 REGWRITE32(vdac
, bt_reg
, cp
[5]);
540 REGWRITE32(vdac
, bt_reg
, cp
[0]);
541 REGWRITE32(vdac
, bt_reg
, cp
[2]);
542 REGWRITE32(vdac
, bt_reg
, cp
[4]);
544 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
545 uint8_t *ip
, *mp
, img
, msk
;
549 ip
= (uint8_t *)sc
->sc_cursor
.cc_image
;
550 mp
= (uint8_t *)sc
->sc_cursor
.cc_mask
;
553 VDACSELECT(vdac
, BT459_IREG_CRAM_BASE
+0);
554 /* 64 pixel scan line is consisted with 16 byte cursor ram */
555 while (bcnt
< sc
->sc_cursor
.cc_size
.y
* 16) {
556 /* pad right half 32 pixel when smaller than 33 */
557 if ((bcnt
& 0x8) && sc
->sc_cursor
.cc_size
.x
< 33) {
558 REGWRITE32(vdac
, bt_reg
, 0);
559 REGWRITE32(vdac
, bt_reg
, 0);
564 img
&= msk
; /* cookie off image */
565 u
= (msk
& 0x0f) << 4 | (img
& 0x0f);
566 REGWRITE32(vdac
, bt_reg
, shuffle
[u
]);
567 u
= (msk
& 0xf0) | (img
& 0xf0) >> 4;
568 REGWRITE32(vdac
, bt_reg
, shuffle
[u
]);
572 /* pad unoccupied scan lines */
573 while (bcnt
< CURSOR_MAX_SIZE
* 16) {
574 REGWRITE32(vdac
, bt_reg
, 0);
575 REGWRITE32(vdac
, bt_reg
, 0);
579 if (v
& WSDISPLAY_CMAP_DOLUT
) {
580 struct hwcmap256
*cm
= &sc
->sc_cmap
;
584 for (index
= 0; index
< CMAP_SIZE
; index
++) {
585 REGWRITE32(vdac
, bt_cmap
, cm
->r
[index
]);
586 REGWRITE32(vdac
, bt_cmap
, cm
->g
[index
]);
587 REGWRITE32(vdac
, bt_cmap
, cm
->b
[index
]);
595 cfbhwinit(void *cfbbase
)
597 char *vdac
= (char *)cfbbase
+ CX_BT459_OFFSET
;
601 VDACSELECT(vdac
, BT459_IREG_COMMAND_0
);
602 REGWRITE32(vdac
, bt_reg
, 0x40); /* CMD0 */
603 REGWRITE32(vdac
, bt_reg
, 0x0); /* CMD1 */
604 REGWRITE32(vdac
, bt_reg
, 0xc0); /* CMD2 */
605 REGWRITE32(vdac
, bt_reg
, 0xff); /* PRM */
606 REGWRITE32(vdac
, bt_reg
, 0); /* 205 */
607 REGWRITE32(vdac
, bt_reg
, 0x0); /* PBM */
608 REGWRITE32(vdac
, bt_reg
, 0); /* 207 */
609 REGWRITE32(vdac
, bt_reg
, 0x0); /* ORM */
610 REGWRITE32(vdac
, bt_reg
, 0x0); /* OBM */
611 REGWRITE32(vdac
, bt_reg
, 0x0); /* ILV */
612 REGWRITE32(vdac
, bt_reg
, 0x0); /* TEST */
614 VDACSELECT(vdac
, BT459_IREG_CCR
);
615 REGWRITE32(vdac
, bt_reg
, 0x0);
616 REGWRITE32(vdac
, bt_reg
, 0x0);
617 REGWRITE32(vdac
, bt_reg
, 0x0);
618 REGWRITE32(vdac
, bt_reg
, 0x0);
619 REGWRITE32(vdac
, bt_reg
, 0x0);
620 REGWRITE32(vdac
, bt_reg
, 0x0);
621 REGWRITE32(vdac
, bt_reg
, 0x0);
622 REGWRITE32(vdac
, bt_reg
, 0x0);
623 REGWRITE32(vdac
, bt_reg
, 0x0);
624 REGWRITE32(vdac
, bt_reg
, 0x0);
625 REGWRITE32(vdac
, bt_reg
, 0x0);
626 REGWRITE32(vdac
, bt_reg
, 0x0);
627 REGWRITE32(vdac
, bt_reg
, 0x0);
629 /* build sane colormap */
632 for (i
= 0; i
< CMAP_SIZE
; i
++, p
+= 3) {
633 REGWRITE32(vdac
, bt_cmap
, p
[0]);
634 REGWRITE32(vdac
, bt_cmap
, p
[1]);
635 REGWRITE32(vdac
, bt_cmap
, p
[2]);
638 /* clear out cursor image */
639 VDACSELECT(vdac
, BT459_IREG_CRAM_BASE
);
640 for (i
= 0; i
< 1024; i
++)
641 REGWRITE32(vdac
, bt_reg
, 0xff);
644 * 2 bit/pixel cursor. Assign MSB for cursor mask and LSB for
645 * cursor image. CCOLOR_2 for mask color, while CCOLOR_3 for
646 * image color. CCOLOR_1 will be never used.
648 VDACSELECT(vdac
, BT459_IREG_CCOLOR_1
);
649 REGWRITE32(vdac
, bt_reg
, 0xff);
650 REGWRITE32(vdac
, bt_reg
, 0xff);
651 REGWRITE32(vdac
, bt_reg
, 0xff);
653 REGWRITE32(vdac
, bt_reg
, 0);
654 REGWRITE32(vdac
, bt_reg
, 0);
655 REGWRITE32(vdac
, bt_reg
, 0);
657 REGWRITE32(vdac
, bt_reg
, 0xff);
658 REGWRITE32(vdac
, bt_reg
, 0xff);
659 REGWRITE32(vdac
, bt_reg
, 0xff);
663 get_cmap(struct cfb_softc
*sc
, struct wsdisplay_cmap
*p
)
665 u_int index
= p
->index
, count
= p
->count
;
668 if (index
>= CMAP_SIZE
|| count
> CMAP_SIZE
- index
)
671 error
= copyout(&sc
->sc_cmap
.r
[index
], p
->red
, count
);
674 error
= copyout(&sc
->sc_cmap
.g
[index
], p
->green
, count
);
677 error
= copyout(&sc
->sc_cmap
.b
[index
], p
->blue
, count
);
682 set_cmap(struct cfb_softc
*sc
, struct wsdisplay_cmap
*p
)
684 struct hwcmap256 cmap
;
685 u_int index
= p
->index
, count
= p
->count
;
688 if (index
>= CMAP_SIZE
|| count
> CMAP_SIZE
- index
)
691 error
= copyin(p
->red
, &cmap
.r
[index
], count
);
694 error
= copyin(p
->green
, &cmap
.g
[index
], count
);
697 error
= copyin(p
->blue
, &cmap
.b
[index
], count
);
701 memcpy(&sc
->sc_cmap
.r
[index
], &cmap
.r
[index
], count
);
702 memcpy(&sc
->sc_cmap
.g
[index
], &cmap
.g
[index
], count
);
703 memcpy(&sc
->sc_cmap
.b
[index
], &cmap
.b
[index
], count
);
704 sc
->sc_changed
|= WSDISPLAY_CMAP_DOLUT
;
710 set_cursor(struct cfb_softc
*sc
, struct wsdisplay_cursor
*p
)
712 #define cc (&sc->sc_cursor)
713 u_int v
, index
= 0, count
= 0, icount
= 0;
714 uint8_t r
[2], g
[2], b
[2], image
[512], mask
[512];
718 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
719 index
= p
->cmap
.index
;
720 count
= p
->cmap
.count
;
721 if (index
>= 2 || (index
+ count
) > 2)
723 error
= copyin(p
->cmap
.red
, &r
[index
], count
);
726 error
= copyin(p
->cmap
.green
, &g
[index
], count
);
729 error
= copyin(p
->cmap
.blue
, &b
[index
], count
);
733 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
734 if (p
->size
.x
> CURSOR_MAX_SIZE
|| p
->size
.y
> CURSOR_MAX_SIZE
)
736 icount
= ((p
->size
.x
< 33) ? 4 : 8) * p
->size
.y
;
737 error
= copyin(p
->image
, image
, icount
);
740 error
= copyin(p
->mask
, mask
, icount
);
746 if (v
& WSDISPLAY_CURSOR_DOCUR
)
747 sc
->sc_curenb
= p
->enable
;
748 if (v
& WSDISPLAY_CURSOR_DOPOS
)
749 set_curpos(sc
, &p
->pos
);
750 if (v
& WSDISPLAY_CURSOR_DOHOT
)
752 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
753 memcpy(&cc
->cc_color
[index
], &r
[index
], count
);
754 memcpy(&cc
->cc_color
[index
+ 2], &g
[index
], count
);
755 memcpy(&cc
->cc_color
[index
+ 4], &b
[index
], count
);
757 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
758 cc
->cc_size
= p
->size
;
759 memset(cc
->cc_image
, 0, sizeof cc
->cc_image
);
760 memcpy(cc
->cc_image
, image
, icount
);
761 memset(cc
->cc_mask
, 0, sizeof cc
->cc_mask
);
762 memcpy(cc
->cc_mask
, mask
, icount
);
772 get_cursor(struct cfb_softc
*sc
, struct wsdisplay_cursor
*p
)
774 return (EPASSTHROUGH
); /* XXX */
778 set_curpos(struct cfb_softc
*sc
, struct wsdisplay_curpos
*curpos
)
780 struct rasops_info
*ri
= sc
->sc_ri
;
781 int x
= curpos
->x
, y
= curpos
->y
;
785 else if (y
> ri
->ri_height
)
789 else if (x
> ri
->ri_width
)
791 sc
->sc_cursor
.cc_pos
.x
= x
;
792 sc
->sc_cursor
.cc_pos
.y
= y
;