hd64461video.c revision 1.5 1 /* $NetBSD: hd64461video.c,v 1.5 2001/12/05 22:16:30 atatat Exp $ */
2
3 /*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38 // #define HD64461VIDEO_DEBUG
39 // #define HD64461VIDEO_HWACCEL
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/device.h>
44 #include <sys/malloc.h>
45
46 #include <sys/conf.h> /* cdev_decl */
47 #include <dev/cons.h> /* consdev */
48
49 /* ioctl */
50 #include <sys/ioctl.h>
51 #include <sys/buf.h>
52 #include <uvm/uvm_extern.h>
53
54 #include <machine/bus.h>
55 #include <machine/intr.h>
56
57 #include <hpcsh/dev/hd64461/hd64461var.h>
58 #include <hpcsh/dev/hd64461/hd64461reg.h>
59 #include <hpcsh/dev/hd64461/hd64461videoreg.h>
60
61 #include <dev/wscons/wsdisplayvar.h>
62 #include <dev/rasops/rasops.h>
63
64 #include <dev/wscons/wsconsio.h>
65 #include <dev/hpc/hpcfbvar.h>
66 #include <dev/hpc/hpcfbio.h>
67 #include <dev/hpc/video_subr.h>
68
69 #include <machine/bootinfo.h>
70
71 #ifdef HD64461VIDEO_DEBUG
72 #include <hpcsh/hpcsh/debug.h>
73 #endif
74
75 #ifdef HD64461VIDEO_DEBUG
76 int hd64461video_debug = 1;
77 #define DPRINTF(fmt, args...) \
78 if (hd64461video_debug) \
79 printf("%s: " fmt, __FUNCTION__ , ##args)
80 #define DPRINTFN(n, arg) \
81 if (hd64461video_debug > (n)) \
82 printf("%s: " fmt, __FUNCTION__ , ##args)
83 #else
84 #define DPRINTF(arg...) ((void)0)
85 #define DPRINTFN(n, arg...) ((void)0)
86 #endif
87
88 struct hd64461video_chip;
89 struct hd64461video_font {
90 struct wsdisplay_font wsfont;
91 int c, cw, cstep;
92 int loaded;
93 };
94
95 struct hd64461video_softc {
96 struct device sc_dev;
97 enum hd64461_module_id sc_module_id;
98 struct hd64461video_chip *sc_vc;
99
100 struct hd64461video_font sc_font;
101 };
102
103 static struct hd64461video_chip {
104 struct video_chip vc;
105 enum hd64461video_display_mode {
106 LCD256_C,
107 LCD64K_C,
108 LCD64_MONO,
109 LCD16_MONO,
110 LCD4_MONO,
111 LCD2_MONO,
112 CRT256_C,
113 LCDCRT
114 };
115 enum hd64461video_display_mode mode;
116 struct hpcfb_dspconf hd;
117 struct hpcfb_fbconf hf;
118 u_int8_t *off_screen_addr;
119 size_t off_screen_size;
120
121 int console;
122 } hd64461video_chip;
123
124 static int hd64461video_match(struct device *, struct cfdata *, void *);
125 static void hd64461video_attach(struct device *, struct device *, void *);
126 void hd64461video_cnprobe(struct consdev *);
127 void hd64461video_cninit(struct consdev *);
128
129 static void setup_hpcfbif(struct hd64461video_chip *);
130 static void update_videochip_status(struct hd64461video_chip *);
131 static size_t frame_buffer_size(struct hd64461video_chip *);
132 static void hwaccel_init(struct hd64461video_chip *);
133
134 static void set_clut(struct hd64461video_chip *, int, int, u_int8_t *,
135 u_int8_t *, u_int8_t *);
136 static void get_clut(struct hd64461video_chip *, int, int, u_int8_t *,
137 u_int8_t *, u_int8_t *);
138 static void set_display_mode(struct hd64461video_chip *) __attribute__((__unused__));
139 static void set_display_mode_lcdc(struct hd64461video_chip *);
140 static void set_display_mode_crtc(struct hd64461video_chip *);
141
142 #ifdef HD64461VIDEO_DEBUG
143 static void _info(struct hd64461video_softc *) __attribute__((__unused__));
144 static void _dump(void) __attribute__((__unused__));
145 #endif
146
147 struct cfattach hd64461video_ca = {
148 sizeof(struct hd64461video_softc), hd64461video_match,
149 hd64461video_attach
150 };
151
152 int hd64461video_ioctl(void *, u_long, caddr_t, int, struct proc *);
153 paddr_t hd64461video_mmap(void *, off_t, int);
154 void hd64461video_cursor(void *, int, int, int, int, int);
155 void hd64461video_bitblit(void *, int, int, int, int, int, int);
156 void hd64461video_erase(void *, int, int, int, int, int);
157 void hd64461video_putchar(void *, int, int, struct wsdisplay_font *, int, int,
158 u_int, int);
159 void hd64461video_setclut(void *, struct rasops_info *);
160 void hd64461video_font(void *, struct wsdisplay_font *);
161 void hd64461video_iodone(void *);
162
163 struct hpcfb_accessops hd64461video_ha = {
164 .ioctl = hd64461video_ioctl,
165 .mmap = hd64461video_mmap,
166 #ifdef HD64461VIDEO_HWACCEL
167 .cursor = hd64461video_cursor,
168 .bitblit= hd64461video_bitblit,
169 .erase = hd64461video_erase,
170 .putchar= hd64461video_putchar,
171 .setclut= hd64461video_setclut,
172 .font = hd64461video_font,
173 .iodone = hd64461video_iodone
174 #endif /* HD64461VIDEO_HWACCEL */
175 };
176
177 /* font */
178 static void font_load_16bpp(u_int16_t *, u_int8_t *, int, int, int);
179 static void font_load_8bpp(u_int8_t *, u_int8_t *, int, int, int);
180 static void font_set_attr(struct hd64461video_softc *, struct wsdisplay_font *);
181 static void font_load(struct hd64461video_softc *);
182 static vaddr_t font_start_addr(struct hd64461video_softc *, int);
183
184 static int
185 hd64461video_match(struct device *parent, struct cfdata *cf, void *aux)
186 {
187 struct hd64461_attach_args *ha = aux;
188
189 return (ha->ha_module_id == HD64461_MODULE_VIDEO);
190 }
191
192 static void
193 hd64461video_attach(struct device *parent, struct device *self, void *aux)
194 {
195 struct hd64461_attach_args *ha = aux;
196 struct hd64461video_softc *sc = (struct hd64461video_softc *)self;
197 struct hpcfb_attach_args hfa;
198 struct video_chip *vc = &hd64461video_chip.vc;
199 char pbuf[9];
200 size_t fbsize, on_screen_size;
201
202 sc->sc_module_id = ha->ha_module_id;
203 sc->sc_vc = &hd64461video_chip;
204 printf(": ");
205
206 /* detect frame buffer size */
207 fbsize = frame_buffer_size(&hd64461video_chip);
208 format_bytes(pbuf, sizeof(pbuf), fbsize);
209 printf("frame buffer = %s ", pbuf);
210
211 /* update chip status */
212 update_videochip_status(&hd64461video_chip);
213 // set_display_mode(&hd64461video_chip);
214
215 if (hd64461video_chip.console)
216 printf(", console");
217
218 printf("\n");
219 #ifdef HD64461VIDEO_DEBUG
220 _info(sc);
221 _dump();
222 #endif
223
224
225 /* setup hpcfb interface */
226 setup_hpcfbif(&hd64461video_chip);
227
228 /* setup off-screen buffer */
229 on_screen_size = (vc->vc_fbwidth * vc->vc_fbheight * vc->vc_fbdepth) /
230 NBBY;
231 hd64461video_chip.off_screen_addr = (u_int8_t *)vc->vc_fbvaddr +
232 on_screen_size;
233 hd64461video_chip.off_screen_size = fbsize - on_screen_size;
234 /* clean up off-screen area */
235 {
236 u_int8_t *p = hd64461video_chip.off_screen_addr;
237 u_int8_t *end = p + hd64461video_chip.off_screen_size;
238 while (p < end)
239 *p++ = 0xff;
240 }
241
242 /* initialize hardware acceralation */
243 hwaccel_init(&hd64461video_chip);
244
245 /* register interface to hpcfb */
246 hfa.ha_console = hd64461video_chip.console;
247 hfa.ha_accessops = &hd64461video_ha;
248 hfa.ha_accessctx = sc;
249 hfa.ha_curfbconf = 0;
250 hfa.ha_nfbconf = 1;
251 hfa.ha_fbconflist = &hd64461video_chip.hf;
252 hfa.ha_curdspconf = 0;
253 hfa.ha_ndspconf = 1;
254 hfa.ha_dspconflist = &hd64461video_chip.hd;
255
256 config_found(self, &hfa, hpcfbprint);
257 }
258
259 /* console support */
260 void
261 hd64461video_cninit(struct consdev *cndev)
262 {
263 hd64461video_chip.console = 1;
264 hd64461video_chip.vc.vc_reverse = video_reverse_color();
265
266 update_videochip_status(&hd64461video_chip);
267 setup_hpcfbif(&hd64461video_chip);
268 hpcfb_cnattach(&hd64461video_chip.hf);
269
270 cn_tab->cn_pri = CN_INTERNAL;
271 }
272
273 void
274 hd64461video_cnprobe(struct consdev *cndev)
275 {
276 #if NWSDISPLAY > 0
277 int maj, unit;
278 #endif
279 cndev->cn_dev = NODEV;
280 cndev->cn_pri = CN_NORMAL;
281
282 #if NWSDISPLAY > 0
283 unit = 0;
284 for (maj = 0; maj < nchrdev; maj++) {
285 if (cdevsw[maj].d_open == wsdisplayopen)
286 break;
287 }
288
289 if (maj != nchrdev) {
290 cndev->cn_pri = CN_INTERNAL;
291 cndev->cn_dev = makedev(maj, unit);
292 }
293 #endif /* NWSDISPLAY > 0 */
294 }
295
296 /* hpcfb support */
297 static void
298 setup_hpcfbif(struct hd64461video_chip *hvc)
299 {
300 struct video_chip *vc = &hvc->vc;
301 struct hpcfb_fbconf *fb = &hvc->hf;
302 vaddr_t fbvaddr = vc->vc_fbvaddr;
303 int height = vc->vc_fbheight;
304 int width = vc->vc_fbwidth;
305 int depth = vc->vc_fbdepth;
306
307 memset(fb, 0, sizeof(struct hpcfb_fbconf));
308
309 fb->hf_conf_index = 0; /* configuration index */
310 fb->hf_nconfs = 1; /* how many configurations */
311 strncpy(fb->hf_name, "HD64461 video module", HPCFB_MAXNAMELEN);
312
313 /* frame buffer name */
314 strncpy(fb->hf_conf_name, "LCD", HPCFB_MAXNAMELEN);
315
316 /* configuration name */
317 fb->hf_height = height;
318 fb->hf_width = width;
319 fb->hf_baseaddr = (u_long)fbvaddr;
320 fb->hf_offset = (u_long)fbvaddr -
321 sh3_ptob(sh3_btop(fbvaddr));
322
323 /* frame buffer start offset */
324 fb->hf_bytes_per_line = (width * depth) / NBBY;
325 fb->hf_nplanes = 1;
326 fb->hf_bytes_per_plane = height * fb->hf_bytes_per_line;
327
328 fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
329 fb->hf_access_flags |= HPCFB_ACCESS_WORD;
330 fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
331 if (vc->vc_reverse)
332 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
333
334 switch (depth) {
335 default:
336 panic("%s: not supported color depth\n", __FUNCTION__);
337 /* NOTREACHED */
338 case 16:
339 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
340 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
341 fb->hf_pack_width = 16;
342 fb->hf_pixels_per_pack = 1;
343 fb->hf_pixel_width = 16;
344
345 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
346 /* reserved for future use */
347 fb->hf_u.hf_rgb.hf_flags = 0;
348
349 fb->hf_u.hf_rgb.hf_red_width = 5;
350 fb->hf_u.hf_rgb.hf_red_shift = 11;
351 fb->hf_u.hf_rgb.hf_green_width = 6;
352 fb->hf_u.hf_rgb.hf_green_shift = 5;
353 fb->hf_u.hf_rgb.hf_blue_width = 5;
354 fb->hf_u.hf_rgb.hf_blue_shift = 0;
355 fb->hf_u.hf_rgb.hf_alpha_width = 0;
356 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
357 break;
358
359 case 8:
360 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
361 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
362 fb->hf_pack_width = 8;
363 fb->hf_pixels_per_pack = 1;
364 fb->hf_pixel_width = 8;
365 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
366 /* reserved for future use */
367 fb->hf_u.hf_indexed.hf_flags = 0;
368 break;
369 }
370 }
371
372 static void
373 hwaccel_init(struct hd64461video_chip *hvc)
374 {
375 u_int16_t r;
376
377 r = HD64461_LCDGRCFGR_ACCRESET;
378 switch (hvc->vc.vc_fbdepth) {
379 default:
380 panic("no bitblit acceralation.");
381 case 16:
382 break;
383 case 8:
384 r |= HD64461_LCDGRCFGR_COLORDEPTH_8BPP;
385 break;
386 }
387 hd64461_reg_write_2(HD64461_LCDGRCFGR_REG16, r);
388
389 while ((hd64461_reg_read_2(HD64461_LCDGRCFGR_REG16) &
390 HD64461_LCDGRCFGR_ACCSTATUS) != 0)
391 /* busy loop */;
392 r &= ~HD64461_LCDGRCFGR_ACCRESET;
393 hd64461_reg_write_2(HD64461_LCDGRCFGR_REG16, r);
394
395 while ((hd64461_reg_read_2(HD64461_LCDGRCFGR_REG16) &
396 HD64461_LCDGRCFGR_ACCSTATUS) != 0)
397 /* busy loop */;
398
399 hd64461_reg_write_2(HD64461_LCDGRDOR_REG16,
400 (hvc->vc.vc_fbwidth - 1) & HD64461_LCDGRDOR_MASK);
401 }
402
403 /* hpcfb ops */
404 int
405 hd64461video_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
406 {
407 struct hd64461video_softc *sc = (struct hd64461video_softc *)v;
408 struct hpcfb_fbconf *hf = &sc->sc_vc->hf;
409 struct hpcfb_fbconf *fbconf;
410 struct hpcfb_dspconf *dspconf;
411 struct wsdisplay_cmap *cmap;
412 u_int8_t *r, *g, *b;
413 int error;
414 size_t idx, cnt;
415
416 switch (cmd) {
417 case WSDISPLAYIO_GETCMAP:
418 cmap = (struct wsdisplay_cmap*)data;
419 cnt = cmap->count;
420 idx = cmap->index;
421
422 if (hf->hf_class != HPCFB_CLASS_INDEXCOLOR ||
423 hf->hf_pack_width != 8 ||
424 !LEGAL_CLUT_INDEX(idx) ||
425 !LEGAL_CLUT_INDEX(idx + cnt -1)) {
426 return (EINVAL);
427 }
428
429 if (!uvm_useracc(cmap->red, cnt, B_WRITE) ||
430 !uvm_useracc(cmap->green, cnt, B_WRITE) ||
431 !uvm_useracc(cmap->blue, cnt, B_WRITE)) {
432 return (EFAULT);
433 }
434
435 error = cmap_work_alloc(&r, &g, &b, 0, cnt);
436 if (error != 0) {
437 cmap_work_free(r, g, b, 0);
438 return (ENOMEM);
439 }
440
441 get_clut(sc->sc_vc, idx, cnt, r, g, b);
442 copyout(r, cmap->red, cnt);
443 copyout(g, cmap->green,cnt);
444 copyout(b, cmap->blue, cnt);
445 cmap_work_free(r, g, b, 0);
446
447 return (0);
448
449 case WSDISPLAYIO_PUTCMAP:
450 cmap = (struct wsdisplay_cmap *)data;
451 cnt = cmap->count;
452 idx = cmap->index;
453
454 if (hf->hf_class != HPCFB_CLASS_INDEXCOLOR ||
455 hf->hf_pack_width != 8 ||
456 !LEGAL_CLUT_INDEX(idx) ||
457 !LEGAL_CLUT_INDEX(idx + cnt -1)) {
458 return (EINVAL);
459 }
460
461 if (!uvm_useracc(cmap->red, cnt, B_WRITE) ||
462 !uvm_useracc(cmap->green, cnt, B_WRITE) ||
463 !uvm_useracc(cmap->blue, cnt, B_WRITE)) {
464 return (EFAULT);
465 }
466
467 error = cmap_work_alloc(&r, &g, &b, 0, cnt);
468 if (error != 0) {
469 cmap_work_free(r, g, b, 0);
470 return (ENOMEM);
471 }
472
473 copyin(cmap->red, r, cnt);
474 copyin(cmap->green,g, cnt);
475 copyin(cmap->blue, b, cnt);
476 set_clut(sc->sc_vc, idx, cnt, r, g, b);
477 cmap_work_free(r, g, b, 0);
478
479 return (0);
480
481 case HPCFBIO_GCONF:
482 fbconf = (struct hpcfb_fbconf *)data;
483 if (fbconf->hf_conf_index != 0 &&
484 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
485 return (EINVAL);
486 }
487 *fbconf = *hf; /* structure assignment */
488 return (0);
489
490 case HPCFBIO_SCONF:
491 fbconf = (struct hpcfb_fbconf *)data;
492 if (fbconf->hf_conf_index != 0 &&
493 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
494 return (EINVAL);
495 }
496 /*
497 * nothing to do because we have only one configration
498 */
499 return (0);
500
501 case HPCFBIO_GDSPCONF:
502 dspconf = (struct hpcfb_dspconf *)data;
503 if ((dspconf->hd_unit_index != 0 &&
504 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
505 (dspconf->hd_conf_index != 0 &&
506 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
507 return (EINVAL);
508 }
509 *dspconf = sc->sc_vc->hd; /* structure assignment */
510 return (0);
511
512 case HPCFBIO_SDSPCONF:
513 dspconf = (struct hpcfb_dspconf *)data;
514 if ((dspconf->hd_unit_index != 0 &&
515 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
516 (dspconf->hd_conf_index != 0 &&
517 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
518 return (EINVAL);
519 }
520 /*
521 * nothing to do
522 * because we have only one unit and one configration
523 */
524 return (0);
525
526 case HPCFBIO_GOP:
527 case HPCFBIO_SOP:
528 /* XXX not implemented yet */
529 return (EINVAL);
530 }
531
532 return (ENOTTY);
533 }
534
535 paddr_t
536 hd64461video_mmap(void *ctx, off_t offset, int prot)
537 {
538 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
539 struct hpcfb_fbconf *hf = &sc->sc_vc->hf;
540
541 if (offset < 0 || (hf->hf_bytes_per_plane + hf->hf_offset) < offset)
542 return (-1);
543
544 return (sh3_btop(HD64461_FBBASE + offset));
545 }
546
547 void
548 hd64461video_cursor(void *ctx, int on, int xd, int yd, int w, int h)
549 {
550 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
551 int xw, yh, width, bpp, adr;
552 u_int16_t r;
553
554 width = sc->sc_vc->vc.vc_fbwidth;
555 bpp = sc->sc_vc->vc.vc_fbdepth;
556 xw = w - 1;
557 yh = h - 1;
558
559 /* Wait until previous command done. */
560 hd64461video_iodone(ctx);
561
562 /* Destination addr */
563 adr = width * yd + xd;
564 if (bpp == 16)
565 adr *= 2;
566 hd64461_reg_write_2(HD64461_LCDBBTDSARH_REG16,
567 HD64461_LCDBBTDSARH(adr));
568 hd64461_reg_write_2(HD64461_LCDBBTDSARL_REG16,
569 HD64461_LCDBBTDSARL(adr));
570
571 // Width
572 hd64461_reg_write_2(HD64461_LCDBBTDWR_REG16,
573 xw & HD64461_LCDBBTDWR_MASK);
574
575 // Height
576 hd64461_reg_write_2(HD64461_LCDBBTDHR_REG16,
577 yh & HD64461_LCDBBTDHR_MASK);
578
579 // Operation (Destination Invert)
580 hd64461_reg_write_2(HD64461_LCDBBTROPR_REG16,
581 HD64461_LCDC_BITBLT_DSTINVERT);
582
583 // BitBLT mode (Destination Invert)
584 hd64461_reg_write_2(HD64461_LCDBBTMDR_REG16, 0);
585
586 // Kick.
587 r = hd64461_reg_read_2(HD64461_LCDGRCFGR_REG16);
588 r &= ~HD64461_LCDGRCFGR_ACCSTART_MASK;
589 r |= HD64461_LCDGRCFGR_ACCSTART_BITBLT;
590 hd64461_reg_write_2(HD64461_LCDGRCFGR_REG16, r);
591 }
592
593 void
594 hd64461video_bitblit(void *ctx, int xs, int ys, int xd, int yd, int h, int w)
595 {
596 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
597 int xw, yh, width, bpp, condition_a, adr;
598 u_int16_t r;
599
600 xw = w - 1;
601 yh = h - 1;
602 width = sc->sc_vc->vc.vc_fbwidth;
603 bpp = sc->sc_vc->vc.vc_fbdepth;
604 condition_a = ((ys == yd) && (xs <= xd)) || (ys < yd);
605
606 hd64461video_iodone(ctx);
607
608 // Source addr
609 if (condition_a)
610 adr = (width * (ys + yh)) + (xs + xw);
611 else
612 adr = width * ys + xs;
613 if (bpp == 16)
614 adr *= 2;
615
616 hd64461_reg_write_2(HD64461_LCDBBTSSARH_REG16,
617 HD64461_LCDBBTSSARH(adr));
618 hd64461_reg_write_2(HD64461_LCDBBTSSARL_REG16,
619 HD64461_LCDBBTSSARL(adr));
620
621 // Destination addr
622 if (condition_a)
623 adr = (width * (yd + yh)) + (xd + xw);
624 else
625 adr = width * yd + xd;
626 if (bpp == 16)
627 adr *= 2;
628
629 hd64461_reg_write_2(HD64461_LCDBBTDSARH_REG16,
630 HD64461_LCDBBTDSARH(adr));
631 hd64461_reg_write_2(HD64461_LCDBBTDSARL_REG16,
632 HD64461_LCDBBTDSARL(adr));
633
634 // Width
635 hd64461_reg_write_2(HD64461_LCDBBTDWR_REG16,
636 xw & HD64461_LCDBBTDWR_MASK);
637
638 // Height
639 hd64461_reg_write_2(HD64461_LCDBBTDHR_REG16,
640 yh & HD64461_LCDBBTDHR_MASK);
641
642 // Operation (source copy)
643 hd64461_reg_write_2(HD64461_LCDBBTROPR_REG16,
644 HD64461_LCDC_BITBLT_SRCCOPY);
645
646 // BitBLT mode (on screen to on screen)
647 r = HD64461_LCDBBTMDR_SET(0,
648 HD64461_LCDBBTMDR_ON_SCREEN_TO_ON_SCREEN);
649 hd64461_reg_write_2(HD64461_LCDBBTMDR_REG16, r);
650
651 // Kick.
652 r = hd64461_reg_read_2(HD64461_LCDGRCFGR_REG16);
653 r &= ~HD64461_LCDGRCFGR_ACCSTART_MASK;
654 r |= HD64461_LCDGRCFGR_ACCSTART_BITBLT;
655 hd64461_reg_write_2(HD64461_LCDGRCFGR_REG16, r);
656 }
657
658 void
659 hd64461video_erase(void *ctx, int xd, int yd, int h, int w, int attr)
660 {
661 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
662 int xw, yh, width, bpp, adr;
663 u_int16_t r;
664
665 width = sc->sc_vc->vc.vc_fbwidth;
666 bpp = sc->sc_vc->vc.vc_fbdepth;
667 xw = w - 1;
668 yh = h - 1;
669
670 /* Wait until previous command done. */
671 hd64461video_iodone(ctx);
672
673 /* Destination addr */
674 adr = width * yd + xd;
675 if (bpp == 16)
676 adr *= 2;
677 hd64461_reg_write_2(HD64461_LCDBBTDSARH_REG16,
678 HD64461_LCDBBTDSARH(adr));
679 hd64461_reg_write_2(HD64461_LCDBBTDSARL_REG16,
680 HD64461_LCDBBTDSARL(adr));
681
682 // Width
683 hd64461_reg_write_2(HD64461_LCDBBTDWR_REG16,
684 xw & HD64461_LCDBBTDWR_MASK);
685
686 // Height
687 hd64461_reg_write_2(HD64461_LCDBBTDHR_REG16,
688 yh & HD64461_LCDBBTDHR_MASK);
689
690 // Color
691 hd64461_reg_write_2(HD64461_LCDGRSCR_REG16, 0); //XXX black only
692
693 // Operation (Solid Color Fill)
694 hd64461_reg_write_2(HD64461_LCDBBTROPR_REG16,
695 HD64461_LCDC_BITBLT_PATCOPY);
696
697 // BitBLT mode (Solid Color)
698 hd64461_reg_write_2(HD64461_LCDBBTMDR_REG16,
699 HD64461_LCDBBTMDR_PATSELECT_SOLIDCOLOR);
700
701 // Kick.
702 r = hd64461_reg_read_2(HD64461_LCDGRCFGR_REG16);
703 r &= ~HD64461_LCDGRCFGR_ACCSTART_MASK;
704 r |= HD64461_LCDGRCFGR_ACCSTART_BITBLT;
705 hd64461_reg_write_2(HD64461_LCDGRCFGR_REG16, r);
706 }
707
708 void
709 hd64461video_putchar(void *ctx, int row, int col, struct wsdisplay_font *font,
710 int fclr, int uclr, u_int uc, int attr)
711 {
712 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
713 int w, h, cw;
714
715 w = font->fontwidth;
716 h = font->fontheight;
717 cw = sc->sc_font.cw;
718 hd64461video_bitblit(ctx, (uc % cw) * w,
719 sc->sc_vc->vc.vc_fbheight + (uc / cw) * h, row, col, h, w);
720 }
721
722 void
723 hd64461video_setclut(void *ctx, struct rasops_info *info)
724 {
725 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
726
727 if (sc->sc_vc->vc.vc_fbdepth != 8)
728 return;
729 }
730
731 void
732 hd64461video_font(void *ctx, struct wsdisplay_font *font)
733 {
734 struct hd64461video_softc *sc = (struct hd64461video_softc *)ctx;
735
736 font_set_attr(sc, font);
737 font_load(sc);
738 }
739
740 void
741 hd64461video_iodone(void *ctx)
742 {
743 while ((hd64461_reg_read_2(HD64461_LCDGRCFGR_REG16) &
744 HD64461_LCDGRCFGR_ACCSTATUS) != 0)
745 /* busy loop */;
746 }
747
748 /* internal */
749 static void
750 font_load_16bpp(u_int16_t *d, u_int8_t *s, int w, int h, int step)
751 {
752 int i, j, n;
753 n = step / sizeof(u_int16_t);
754
755 for (i = 0; i < h; i++, d += n) {
756 for (j = 0; j < w; j++) {
757 d[j] = *s & (1 << (w - j - 1)) ? 0xffff : 0x0000;
758 }
759 s++;
760 }
761 }
762
763 static void
764 font_load_8bpp(u_int8_t *d, u_int8_t *s, int w, int h, int step)
765 {
766 int i, j, n;
767 n = step / sizeof(u_int8_t);
768
769 for (i = 0; i < h; i++, d += n) {
770 for (j = 0; j < w; j++) {
771 d[j] = *s & (1 << (w - j - 1)) ? 0xff : 0x00;
772 }
773 s++;
774 }
775 }
776
777 static void
778 font_set_attr(struct hd64461video_softc *sc, struct wsdisplay_font *f)
779 {
780 struct hd64461video_chip *hvc = sc->sc_vc;
781 struct wsdisplay_font *font = (struct wsdisplay_font *)&sc->sc_font;
782 int w, h, bpp;
783
784 w = f->fontwidth;
785 h = f->fontheight;
786 bpp = hvc->vc.vc_fbdepth;
787
788 *font = *f;
789 sc->sc_font.c = (w * bpp) / NBBY;
790 sc->sc_font.cw = hvc->hf.hf_width / w;
791 sc->sc_font.cstep = ((w * h * bpp) / NBBY) * sc->sc_font.cw;
792
793 DPRINTF("c = %d cw = %d cstep = %d\n", sc->sc_font.c,
794 sc->sc_font.cw, sc->sc_font.cstep);
795
796 }
797
798 /* return frame buffer virtual address of charcter #n */
799 static vaddr_t
800 font_start_addr(struct hd64461video_softc *sc, int n)
801 {
802 struct hd64461video_chip *hvc = sc->sc_vc;
803 struct hd64461video_font *font = &sc->sc_font;
804 vaddr_t base;
805
806 base = (vaddr_t)hvc->off_screen_addr;
807 base += (n / font->cw) * font->cstep + font->c * (n % font->cw);
808
809 return base;
810 }
811
812 static void
813 font_load(struct hd64461video_softc *sc)
814 {
815 struct hd64461video_chip *hvc = sc->sc_vc;
816 struct wsdisplay_font *font = (struct wsdisplay_font *)&sc->sc_font;
817 u_int8_t *q;
818 int w, h, step, i, n;
819
820 if (sc->sc_font.loaded) {
821 printf("reload font\n");
822 }
823
824 w = font->fontwidth;
825 h = font->fontheight;
826 step = sc->sc_font.cw * sc->sc_font.c;
827 n = (w * h) / NBBY;
828 q = font->data;
829
830 DPRINTF("%s (%dx%d) %d+%d\n", font->name, w, h, font->firstchar,
831 font->numchars);
832 DPRINTF("bitorder %d byteorder %d stride %d\n", font->bitorder,
833 font->byteorder, font->stride);
834
835 switch (hvc->vc.vc_fbdepth) {
836 case 8:
837 for (i = font->firstchar; i < font->numchars; i++) {
838 font_load_8bpp((u_int8_t *)font_start_addr(sc, i),
839 q, w, h, step);
840 q += n;
841 }
842 break;
843 case 16:
844 for (i = font->firstchar; i < font->numchars; i++) {
845 font_load_16bpp((u_int16_t *)font_start_addr(sc, i),
846 q, w, h, step);
847 q += n;
848 }
849 break;
850 }
851
852 sc->sc_font.loaded = TRUE;
853 }
854
855 static void
856 update_videochip_status(struct hd64461video_chip *hvc)
857 {
858 struct video_chip *vc = &hvc->vc;
859 u_int16_t r;
860 int i;
861 int depth, width, height;
862
863 /* display mode */
864 r = hd64461_reg_read_2(HD64461_LCDLDR3_REG16);
865 i = HD64461_LCDLDR3_CG(r);
866 switch (i) {
867 case HD64461_LCDLDR3_CG_COLOR16:
868 depth = 16;
869 hvc->mode = LCD64K_C;
870 break;
871 case HD64461_LCDLDR3_CG_COLOR8:
872 depth = 8;
873 hvc->mode = LCD256_C;
874 break;
875 case HD64461_LCDLDR3_CG_GRAY6:
876 depth = 6;
877 hvc->mode = LCD64_MONO;
878 break;
879 case HD64461_LCDLDR3_CG_GRAY4:
880 depth = 4;
881 hvc->mode = LCD16_MONO;
882 break;
883 case HD64461_LCDLDR3_CG_GRAY2:
884 depth = 2;
885 hvc->mode = LCD4_MONO;
886 break;
887 case HD64461_LCDLDR3_CG_GRAY1:
888 depth = 1;
889 hvc->mode = LCD2_MONO;
890 break;
891 }
892
893 r = hd64461_reg_read_2(HD64461_LCDCCR_REG16);
894 i = HD64461_LCDCCR_DSPSEL(i);
895 switch (i) {
896 case HD64461_LCDCCR_DSPSEL_LCD_CRT:
897 depth = 8;
898 hvc->mode = LCDCRT;
899 break;
900 case HD64461_LCDCCR_DSPSEL_CRT:
901 depth = 8;
902 hvc->mode = CRT256_C;
903 break;
904 case HD64461_LCDCCR_DSPSEL_LCD:
905 /* nothing to do */
906 break;
907 }
908
909 width = bootinfo->fb_width;
910 height = bootinfo->fb_height;
911
912 vc->vc_fbvaddr = HD64461_FBBASE;
913 vc->vc_fbpaddr = HD64461_FBBASE;
914 vc->vc_fbdepth = depth;
915 vc->vc_fbsize = (width * height * depth) / NBBY;
916 vc->vc_fbwidth = width;
917 vc->vc_fbheight = height;
918 }
919
920 static void
921 set_display_mode(struct hd64461video_chip *hvc)
922 {
923
924 if (hvc->mode == LCDCRT || hvc->mode == CRT256_C)
925 set_display_mode_crtc(hvc);
926
927 set_display_mode_lcdc(hvc);
928 }
929
930 static void
931 set_display_mode_lcdc(struct hd64461video_chip *hvc)
932 {
933 static struct {
934 u_int16_t clor; /* display size 640 x 240 */
935 u_int16_t ldr3;
936 const char *name;
937 } disp_conf[] = {
938 [LCD256_C] = { 0x280 , HD64461_LCDLDR3_CG_COLOR8 ,
939 "8bit color" },
940 [LCD64K_C] = { 0x500 , HD64461_LCDLDR3_CG_COLOR16 ,
941 "16bit color" },
942 [LCD64_MONO] = { 0x280 , HD64461_LCDLDR3_CG_GRAY6 ,
943 "6bit gray scale" },
944 [LCD16_MONO] = { 0x140 , HD64461_LCDLDR3_CG_GRAY4 ,
945 "4bit gray scale" },
946 [LCD4_MONO] = { 0x0a0 , HD64461_LCDLDR3_CG_GRAY2 ,
947 "2bit gray scale" },
948 [LCD2_MONO] = { 0x050 , HD64461_LCDLDR3_CG_GRAY1 ,
949 "mono chrome" },
950 }, *conf;
951 u_int16_t r;
952 int omode;
953
954 conf = &disp_conf[hvc->mode];
955
956 hd64461_reg_write_2(HD64461_LCDCLOR_REG16, conf->clor);
957 r = hd64461_reg_read_2(HD64461_LCDLDR3_REG16);
958 omode = HD64461_LCDLDR3_CG(r);
959 r = HD64461_LCDLDR3_CG_CLR(r);
960 r = HD64461_LCDLDR3_CG_SET(r, conf->ldr3);
961 hd64461_reg_write_2(HD64461_LCDLDR3_REG16, r);
962
963 printf("%s ", conf->name);
964 }
965
966 static void
967 set_display_mode_crtc(struct hd64461video_chip *hvc)
968 {
969 /* not yet */
970 }
971
972 static size_t
973 frame_buffer_size(struct hd64461video_chip *hvc)
974 {
975 vaddr_t page, startaddr, endaddr;
976 int x;
977
978 startaddr = HD64461_FBBASE;
979 endaddr = startaddr + HD64461_FBSIZE - 1;
980
981 page = startaddr;
982
983 x = random();
984 *(volatile int *)(page + 0) = x;
985 *(volatile int *)(page + 4) = ~x;
986
987 if (*(volatile int *)(page + 0) != x ||
988 *(volatile int *)(page + 4) != ~x)
989 return (0);
990
991 for (page += HD64461_FBPAGESIZE; page < endaddr;
992 page += HD64461_FBPAGESIZE) {
993 if (*(volatile int *)(page + 0) == x &&
994 *(volatile int *)(page + 4) == ~x)
995 goto fbend_found;
996 }
997
998 page -= HD64461_FBPAGESIZE;
999 *(volatile int *)(page + 0) = x;
1000 *(volatile int *)(page + 4) = ~x;
1001
1002 if (*(volatile int *)(page + 0) != x ||
1003 *(volatile int *)(page + 4) != ~x)
1004 return (0);
1005
1006 fbend_found:
1007 return (page - startaddr);
1008 }
1009
1010 static void
1011 set_clut(struct hd64461video_chip *vc, int idx, int cnt,
1012 u_int8_t *r, u_int8_t *g, u_int8_t *b)
1013 {
1014 KASSERT(r && g && b);
1015
1016 /* index pallete */
1017 hd64461_reg_write_2(HD64461_LCDCPTWAR_REG16,
1018 HD64461_LCDCPTWAR_SET(0, idx));
1019 /* set data */
1020 while (cnt && LEGAL_CLUT_INDEX(idx)) {
1021 u_int16_t v;
1022 #define SET_CLUT(x) \
1023 v = (x >> 2) & 0x3f; \
1024 hd64461_reg_write_2(HD64461_LCDCPTWDR_REG16, v)
1025 SET_CLUT(*r);
1026 SET_CLUT(*g);
1027 SET_CLUT(*b);
1028 #undef SET_CLUT
1029 r++, g++, b++;
1030 idx++, cnt--;
1031 }
1032 }
1033
1034 static void
1035 get_clut(struct hd64461video_chip *vc, int idx, int cnt,
1036 u_int8_t *r, u_int8_t *g, u_int8_t *b)
1037 {
1038 KASSERT(r && g && b);
1039
1040 /* index pallete */
1041 hd64461_reg_write_2(HD64461_LCDCPTRAR_REG16,
1042 HD64461_LCDCPTRAR_SET(0, idx));
1043
1044 /* get data */
1045 while (cnt && LEGAL_CLUT_INDEX(idx)) {
1046 u_int16_t v;
1047 #define GET_CLUT(x) \
1048 v = hd64461_reg_read_2(HD64461_LCDCPTWDR_REG16); \
1049 x = HD64461_LCDCPTRDR(v); \
1050 x <<= 2
1051 GET_CLUT(*r);
1052 GET_CLUT(*g);
1053 GET_CLUT(*b);
1054 #undef GET_CLUT
1055 r++, g++, b++;
1056 idx++, cnt--;
1057 }
1058 }
1059
1060 #ifdef HD64461VIDEO_DEBUG
1061 static void
1062 _info(struct hd64461video_softc *sc)
1063 {
1064 const char name[] = __FUNCTION__;
1065 u_int16_t r;
1066 int color;
1067 int i;
1068
1069 dbg_banner_start(name, sizeof name);
1070 printf("---[LCD]---\n");
1071 /* Base Address Register */
1072 r = hd64461_reg_read_2(HD64461_LCDCBAR_REG16);
1073 printf("LCDCBAR Frame buffer base address (4k Byte align): 0x%08x\n",
1074 HD64461_LCDCBAR_BASEADDR(r));
1075
1076 /* Line Address Offset Register */
1077 r = hd64461_reg_read_2(HD64461_LCDCLOR_REG16);
1078 printf("LCDCLOR Line address offset: %d\n", HD64461_LCDCLOR(r));
1079
1080 /* LCDC Control Register */
1081 r = hd64461_reg_read_2(HD64461_LCDCCR_REG16);
1082 i = HD64461_LCDCCR_DSPSEL(r);
1083 #define DBG_BIT_PRINT(r, m) dbg_bit_print(r, HD64461_LCDCCR_##m, #m)
1084 printf("LCDCCR (LCD Control Register)\n");
1085 DBG_BIT_PRINT(r, STBAK);
1086 DBG_BIT_PRINT(r, STREQ);
1087 DBG_BIT_PRINT(r, MOFF);
1088 DBG_BIT_PRINT(r, REFSEL);
1089 DBG_BIT_PRINT(r, EPON);
1090 DBG_BIT_PRINT(r, SPON);
1091 printf("\n");
1092 #undef DBG_BIT_PRINT
1093 printf("LCDCCR Display selct LCD[%c] CRT[%c]\n",
1094 i == HD64461_LCDCCR_DSPSEL_LCD_CRT ||
1095 i == HD64461_LCDCCR_DSPSEL_LCD ? 'x' : '_',
1096 i == HD64461_LCDCCR_DSPSEL_LCD_CRT ||
1097 i == HD64461_LCDCCR_DSPSEL_CRT ? 'x' : '_');
1098
1099 /* LCD Display Register */
1100 /* 1 */
1101 r = hd64461_reg_read_2(HD64461_LCDLDR1_REG16);
1102 printf("(LCD Display Register)\n");
1103 #define DBG_BIT_PRINT(r, m) dbg_bit_print(r, HD64461_LCDLDR1_##m, #m)
1104 printf("LCDLDR1: ");
1105 DBG_BIT_PRINT(r, DINV);
1106 DBG_BIT_PRINT(r, DON);
1107 printf("\n");
1108 #undef DBG_BIT_PRINT
1109 /* 2 */
1110 r = hd64461_reg_read_2(HD64461_LCDLDR2_REG16);
1111 i = HD64461_LCDLDR2_LM(r);
1112 #define DBG_BIT_PRINT(r, m) dbg_bit_print(r, HD64461_LCDLDR2_##m, #m)
1113 printf("LCDLDR2: ");
1114 DBG_BIT_PRINT(r, CC1);
1115 DBG_BIT_PRINT(r, CC2);
1116 #undef DBG_BIT_PRINT
1117 color = 0;
1118 switch (i) {
1119 default:
1120 panic("unknown unknown LCD interface.");
1121 break;
1122 case HD64461_LCDLDR2_LM_COLOR:
1123 color = 1;
1124 printf("Color");
1125 break;
1126 case HD64461_LCDLDR2_LM_GRAY8:
1127 printf("8-bit grayscale");
1128 break;
1129 case HD64461_LCDLDR2_LM_GRAY4:
1130 printf("8-bit grayscale");
1131 break;
1132 }
1133 printf(" LCD interface\n");
1134 /* 3 */
1135 printf("LCDLDR3: ");
1136 r = hd64461_reg_read_2(HD64461_LCDLDR3_REG16);
1137 i = HD64461_LCDLDR3_CS(r);
1138 printf("CS ");
1139 switch (i) {
1140 case 0:
1141 printf("15");
1142 break;
1143 case 1:
1144 printf("2.5");
1145 break;
1146 case 2:
1147 printf("3.75");
1148 break;
1149 case 4:
1150 printf("5");
1151 break;
1152 case 8:
1153 printf("7.5");
1154 break;
1155 case 16:
1156 printf("10");
1157 break;
1158 }
1159 printf("%s MHz ", color ? "" : "/2");
1160 i = HD64461_LCDLDR3_CG(r);
1161 switch (i) {
1162 case HD64461_LCDLDR3_CG_COLOR16:
1163 printf("Color 64K colors\n");
1164 break;
1165 case HD64461_LCDLDR3_CG_COLOR8:
1166 printf("Color 256 colors\n");
1167 break;
1168 case HD64461_LCDLDR3_CG_GRAY6:
1169 printf("6-bit Grayscale\n");
1170 break;
1171 case HD64461_LCDLDR3_CG_GRAY4:
1172 printf("4-bit Grayscale\n");
1173 break;
1174 case HD64461_LCDLDR3_CG_GRAY2:
1175 printf("2-bit Grayscale\n");
1176 break;
1177 case HD64461_LCDLDR3_CG_GRAY1:
1178 printf("1-bit Grayscale\n");
1179 break;
1180 }
1181
1182 /* LCD Number of Characters in Horizontal Register */
1183 r = hd64461_reg_read_2(HD64461_LCDLDHNCR_REG16);
1184 printf("LDHNCR: NHD %d NHT %d (# of horizontal characters)\n",
1185 HD64461_LCDLDHNCR_NHD(r), HD64461_LCDLDHNCR_NHT(r));
1186
1187 /* Start Position of Horizontal Register */
1188 r = hd64461_reg_read_2(HD64461_LCDLDHNSR_REG16);
1189 printf("LDHNSR: HSW %d HSP %d (start position of horizontal)\n",
1190 HD64461_LCDLDHNSR_HSW(r), HD64461_LCDLDHNSR_HSP(r));
1191
1192 /* Total Vertical Lines Register */
1193 r = hd64461_reg_read_2(HD64461_LCDLDVNTR_REG16);
1194 printf("LDVNTR: %d (total vertical lines)\n",
1195 HD64461_LCDLDVNTR_VTL(r));
1196
1197 /* Display Vertical Lines Register */
1198 r = hd64461_reg_read_2(HD64461_LCDLDVNDR_REG16);
1199 printf("LDVNDR: %d (display vertical lines)\n",
1200 HD64461_LCDLDVSPR_VSP(r));
1201
1202 /* Vertical Synchronization Position Register */
1203 r = hd64461_reg_read_2(HD64461_LCDLDVSPR_REG16);
1204 printf("LDVSPR: %d (vertical synchronization position)\n",
1205 HD64461_LCDLDVSPR_VSP(r));
1206
1207 /*
1208 * CRT Control Register
1209 */
1210 printf("---[CRT]---\n");
1211 r = hd64461_reg_read_2(HD64461_LCDCRTVTR_REG16);
1212 printf("CRTVTR: %d (CRTC total vertical lines)\n",
1213 HD64461_LCDCRTVTR(r));
1214 r = hd64461_reg_read_2(HD64461_LCDCRTVRSR_REG16);
1215 printf("CRTVRSR: %d (CRTC vertical retrace start line)\n",
1216 HD64461_LCDCRTVRSR(r));
1217 r = hd64461_reg_read_2(HD64461_LCDCRTVRER_REG16);
1218 printf("CRTVRER: %d (CRTC vertical retrace end line)\n",
1219 HD64461_LCDCRTVRER(r));
1220
1221 dbg_banner_end();
1222 }
1223
1224 static void
1225 _dump()
1226 {
1227 u_int16_t r;
1228 printf("---Display Mode Setting---\n");
1229 #define DUMPREG(x) \
1230 r = hd64461_reg_read_2(HD64461_LCD ## x ## _REG16); \
1231 printf("%-10s 0x%04x ", #x, r); \
1232 bitdisp(r)
1233 DUMPREG(CBAR);
1234 DUMPREG(CLOR);
1235 DUMPREG(CCR);
1236 DUMPREG(LDR1);
1237 DUMPREG(LDR2);
1238 DUMPREG(LDHNCR);
1239 DUMPREG(LDHNSR);
1240 DUMPREG(LDVNTR);
1241 DUMPREG(LDVNDR);
1242 DUMPREG(LDVSPR);
1243 DUMPREG(LDR3);
1244 DUMPREG(CRTVTR);
1245 DUMPREG(CRTVRSR);
1246 DUMPREG(CRTVRER);
1247 #undef DUMPREG
1248 }
1249
1250 #endif /* HD64461VIDEO_DEBUG */
1251