This source file includes following definitions.
- cfxga_install_function
- cfxga_remove_function
- cfxga_match
- cfxga_activate
- cfxga_attach
- cfxga_detach
- cfxga_alloc_screen
- cfxga_burner
- cfxga_free_screen
- cfxga_ioctl
- cfxga_mmap
- cfxga_show_screen
- cfxga_reset_video
- cfxga_reset_and_repaint
- cfxga_wait
- cfxga_synchronize
- cfxga_expand_char
- cfxga_repaint_screen
- cfxga_solid_fill
- cfxga_standalone_rop
- cfxga_copycols
- cfxga_copyrows
- cfxga_do_cursor
- cfxga_erasecols
- cfxga_eraserows
- cfxga_putchar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <sys/param.h>
34 #include <sys/kernel.h>
35 #include <sys/device.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
38 #include <sys/conf.h>
39
40 #include <dev/pcmcia/pcmciavar.h>
41 #include <dev/pcmcia/pcmciareg.h>
42
43 #include <dev/wscons/wsconsio.h>
44 #include <dev/wscons/wsdisplayvar.h>
45 #include <dev/rasops/rasops.h>
46
47 #include <dev/pcmcia/cfxgareg.h>
48
49
50
51
52
53
54 #ifdef CFXGADEBUG
55 #define DPRINTF(arg) printf arg
56 #else
57 #define DPRINTF(arg)
58 #endif
59
60 struct cfxga_screen;
61
62 #define CFXGA_MODE_640x480x16 0
63 #define CFXGA_MODE_800x600x16 1
64 #ifdef ENABLE_8BIT_MODES
65 #define CFXGA_MODE_640x480x8 2
66 #define CFXGA_MODE_800x600x8 3
67 #define CFXGA_NMODES 4
68 #else
69 #define CFXGA_NMODES 2
70 #endif
71
72 struct cfxga_softc {
73 struct device sc_dev;
74 struct pcmcia_function *sc_pf;
75 int sc_state;
76 #define CS_MAPPED 0x0001
77 #define CS_RESET 0x0002
78
79 struct pcmcia_mem_handle sc_pmemh;
80 int sc_memwin;
81 bus_addr_t sc_offset;
82
83 int sc_mode;
84
85 int sc_nscreens;
86 LIST_HEAD(, cfxga_screen) sc_scr;
87 struct cfxga_screen *sc_active;
88
89
90 struct wsscreen_descr sc_wsd[CFXGA_NMODES];
91 struct wsscreen_list sc_wsl;
92 struct wsscreen_descr *sc_scrlist[CFXGA_NMODES];
93 struct wsdisplay_emulops sc_ops;
94 struct device *sc_wsdisplay;
95 };
96
97 int cfxga_match(struct device *, void *, void *);
98 void cfxga_attach(struct device *, struct device *, void *);
99 int cfxga_detach(struct device *, int);
100 int cfxga_activate(struct device *, enum devact);
101
102 struct cfattach cfxga_ca = {
103 sizeof(struct cfxga_softc), cfxga_match, cfxga_attach,
104 cfxga_detach, cfxga_activate
105 };
106
107 struct cfdriver cfxga_cd = {
108 NULL, "cfxga", DV_DULL
109 };
110
111 int cfxga_alloc_screen(void *, const struct wsscreen_descr *, void **,
112 int *, int *, long *);
113 void cfxga_burner(void *, u_int, u_int);
114 void cfxga_free_screen(void *, void *);
115 int cfxga_ioctl(void *, u_long, caddr_t, int, struct proc *);
116 paddr_t cfxga_mmap(void *, off_t, int);
117 int cfxga_show_screen(void *, void *, int, void (*)(void *, int, int),
118 void *);
119
120 struct wsdisplay_accessops cfxga_accessops = {
121 cfxga_ioctl,
122 cfxga_mmap,
123 cfxga_alloc_screen,
124 cfxga_free_screen,
125 cfxga_show_screen,
126 NULL,
127 NULL,
128 NULL,
129 cfxga_burner
130 };
131
132
133
134
135
136 struct cfxga_screen {
137 LIST_ENTRY(cfxga_screen) scr_link;
138 struct cfxga_softc *scr_sc;
139 struct rasops_info scr_ri;
140 struct wsdisplay_charcell *scr_mem;
141 };
142
143 void cfxga_copycols(void *, int, int, int, int);
144 void cfxga_copyrows(void *, int, int, int);
145 void cfxga_do_cursor(struct rasops_info *);
146 void cfxga_erasecols(void *, int, int, int, long);
147 void cfxga_eraserows(void *, int, int, long);
148 void cfxga_putchar(void *, int, int, u_int, long);
149
150 int cfxga_install_function(struct pcmcia_function *);
151 void cfxga_remove_function(struct pcmcia_function *);
152
153 int cfxga_expand_char(struct cfxga_screen *, u_int, int, int, long);
154 int cfxga_repaint_screen(struct cfxga_screen *);
155 void cfxga_reset_video(struct cfxga_softc *);
156 void cfxga_reset_and_repaint(struct cfxga_softc *);
157 int cfxga_solid_fill(struct cfxga_screen *, int, int, int, int, int32_t);
158 int cfxga_standalone_rop(struct cfxga_screen *, u_int,
159 int, int, int, int, int, int);
160 int cfxga_synchronize(struct cfxga_softc *);
161 u_int cfxga_wait(struct cfxga_softc *, u_int, u_int);
162
163 #define cfxga_clear_screen(scr) \
164 cfxga_solid_fill(scr, 0, 0, scr->scr_ri.ri_width, \
165 scr->scr_ri.ri_height, scr->scr_ri.ri_devcmap[WSCOL_BLACK])
166
167 #define cfxga_read_1(sc, addr) \
168 bus_space_read_1((sc)->sc_pmemh.memt, (sc)->sc_pmemh.memh, \
169 (sc)->sc_offset + (addr))
170 #define cfxga_read_2(sc, addr) \
171 bus_space_read_2((sc)->sc_pmemh.memt, (sc)->sc_pmemh.memh, \
172 (sc)->sc_offset + (addr))
173 #define cfxga_write_1(sc, addr, val) \
174 bus_space_write_1((sc)->sc_pmemh.memt, (sc)->sc_pmemh.memh, \
175 (sc)->sc_offset + (addr), (val))
176 #define cfxga_write_2(sc, addr, val) \
177 bus_space_write_2((sc)->sc_pmemh.memt, (sc)->sc_pmemh.memh, \
178 (sc)->sc_offset + (addr), (val))
179
180 #define cfxga_stop_memory_blt(sc) \
181 (void)cfxga_read_2(sc, CFREG_BITBLT_DATA)
182
183 const char *cfxga_modenames[CFXGA_NMODES] = {
184 "640x480x16",
185 "800x600x16",
186 #ifdef ENABLE_8BIT_MODES
187 "640x480x8",
188 "800x600x8"
189 #endif
190 };
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 int
213 cfxga_install_function(struct pcmcia_function *pf)
214 {
215 struct pcmcia_config_entry *cfe;
216
217
218 pf->pf_flags &= ~PFF_FAKE;
219
220
221 pf->ccr_base = 0x800;
222 pf->ccr_mask = 0x67;
223
224
225 cfe = (struct pcmcia_config_entry *)malloc(sizeof *cfe,
226 M_DEVBUF, M_NOWAIT);
227 if (cfe == NULL) {
228 DPRINTF(("%s: cfe allocation failed\n", __func__));
229 return (ENOMEM);
230 }
231
232 bzero(cfe, sizeof *cfe);
233 cfe->number = 42;
234 cfe->flags = PCMCIA_CFE_IO16;
235 cfe->iftype = PCMCIA_IFTYPE_MEMORY;
236
237 SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
238
239 pcmcia_function_init(pf, cfe);
240 return (0);
241 }
242
243
244
245
246
247
248
249 void
250 cfxga_remove_function(struct pcmcia_function *pf)
251 {
252 struct pcmcia_config_entry *cfe;
253
254
255 cfe = SIMPLEQ_FIRST(&pf->cfe_head);
256 SIMPLEQ_REMOVE_HEAD(&pf->cfe_head, cfe_list);
257 free(cfe, M_DEVBUF);
258
259
260 pf->pf_flags |= PFF_FAKE;
261 }
262
263 int
264 cfxga_match(struct device *parent, void *match, void *aux)
265 {
266 struct pcmcia_attach_args *pa = aux;
267 struct pcmcia_function *pf = pa->pf;
268 struct pcmcia_mem_handle h;
269 int rc;
270 int win;
271 bus_addr_t ptr;
272 u_int8_t id = 0;
273
274 if (pa->product != PCMCIA_PRODUCT_INVALID ||
275 pa->manufacturer != PCMCIA_VENDOR_INVALID)
276 return (0);
277
278
279 if ((pf->pf_flags & PFF_FAKE) == 0)
280 return (0);
281
282 if (cfxga_install_function(pf) != 0)
283 return (0);
284
285 if (pcmcia_function_enable(pf) != 0) {
286 DPRINTF(("%s: function enable failed\n"));
287 return (0);
288 }
289
290 rc = pcmcia_mem_alloc(pf, CFXGA_MEM_RANGE, &h);
291 if (rc != 0)
292 goto out;
293
294 rc = pcmcia_mem_map(pf, PCMCIA_MEM_ATTR, 0, CFXGA_MEM_RANGE,
295 &h, &ptr, &win);
296 if (rc != 0)
297 goto out2;
298
299 id = (bus_space_read_1(h.memt, h.memh, ptr + CFREG_REV) &
300 CR_PRODUCT_MASK) >> CR_PRODUCT_SHIFT;
301
302 pcmcia_mem_unmap(pa->pf, win);
303 out2:
304 pcmcia_mem_free(pa->pf, &h);
305 out:
306 pcmcia_function_disable(pf);
307 cfxga_remove_function(pf);
308
309
310
311
312
313 return (id == PRODUCT_S1D13806 ? 10 : 0);
314 }
315
316 int
317 cfxga_activate(struct device *dev, enum devact act)
318 {
319 struct cfxga_softc *sc = (void *)dev;
320
321 switch (act) {
322 case DVACT_ACTIVATE:
323 if (pcmcia_function_enable(sc->sc_pf) != 0) {
324 printf("%s: function enable failed\n",
325 sc->sc_dev.dv_xname);
326 } else {
327 cfxga_reset_and_repaint(sc);
328 }
329 break;
330 case DVACT_DEACTIVATE:
331 pcmcia_function_disable(sc->sc_pf);
332 break;
333 }
334 return (0);
335 }
336
337 void
338 cfxga_attach(struct device *parent, struct device *self, void *aux)
339 {
340 struct cfxga_softc *sc = (void *)self;
341 struct pcmcia_attach_args *pa = aux;
342 struct pcmcia_function *pf = pa->pf;
343 struct wsemuldisplaydev_attach_args waa;
344 struct wsscreen_descr *wsd;
345 u_int i;
346
347 LIST_INIT(&sc->sc_scr);
348 sc->sc_nscreens = 0;
349 sc->sc_pf = pf;
350
351 if (cfxga_install_function(pf) != 0) {
352 printf(": pcmcia function setup failed\n");
353 return;
354 }
355
356 if (pcmcia_function_enable(pf)) {
357 printf(": function enable failed\n");
358 return;
359 }
360
361 if (pcmcia_mem_alloc(pf, CFXGA_MEM_RANGE, &sc->sc_pmemh) != 0) {
362 printf(": can't allocate memory space\n");
363 return;
364 }
365
366 if (pcmcia_mem_map(pf, PCMCIA_MEM_ATTR, 0, CFXGA_MEM_RANGE,
367 &sc->sc_pmemh, &sc->sc_offset, &sc->sc_memwin) != 0) {
368 printf(": can't map frame buffer registers\n");
369 pcmcia_mem_free(pf, &sc->sc_pmemh);
370 return;
371 }
372
373 SET(sc->sc_state, CS_MAPPED);
374
375 printf("\n");
376
377 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
378
379
380
381
382
383
384
385 for (wsd = sc->sc_wsd, i = 0; i < CFXGA_NMODES; wsd++, i++) {
386 strlcpy(wsd->name, cfxga_modenames[i], sizeof(wsd->name));
387 wsd->textops = &sc->sc_ops;
388 sc->sc_scrlist[i] = wsd;
389 }
390 sc->sc_wsl.nscreens = CFXGA_NMODES;
391 sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist;
392
393 waa.console = 0;
394 waa.scrdata = &sc->sc_wsl;
395 waa.accessops = &cfxga_accessops;
396 waa.accesscookie = sc;
397 waa.defaultscreens = 1;
398
399 if ((sc->sc_wsdisplay =
400 config_found(self, &waa, wsemuldisplaydevprint)) == NULL) {
401
402 if (sc->sc_active != NULL)
403 cfxga_clear_screen(sc->sc_active);
404 else
405 cfxga_burner(sc, 0, 0);
406 }
407 }
408
409 int
410 cfxga_detach(struct device *dev, int flags)
411 {
412 struct cfxga_softc *sc = (void *)dev;
413
414
415
416
417 if (sc->sc_wsdisplay != NULL) {
418 config_detach(sc->sc_wsdisplay, DETACH_FORCE);
419
420 }
421
422 if (ISSET(sc->sc_state, CS_MAPPED)) {
423 pcmcia_mem_unmap(sc->sc_pf, sc->sc_memwin);
424 pcmcia_mem_free(sc->sc_pf, &sc->sc_pmemh);
425
426 }
427
428 return (0);
429 }
430
431
432
433
434
435 int
436 cfxga_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
437 int *curxp, int *curyp, long *attrp)
438 {
439 struct cfxga_softc *sc = v;
440 struct cfxga_screen *scr;
441 struct rasops_info *ri;
442 u_int mode, width, height, depth, scrsize;
443
444 scr = malloc(sizeof *scr, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
445 if (scr == NULL)
446 return (ENOMEM);
447 bzero(scr, sizeof *scr);
448
449 mode = type - sc->sc_wsd;
450 #ifdef DIAGNOSTIC
451 if (mode >= CFXGA_NMODES)
452 mode = CFXGA_MODE_640x480x16;
453 #endif
454 switch (mode) {
455 default:
456 case CFXGA_MODE_640x480x16:
457 width = 640;
458 height = 480;
459 depth = 16;
460 break;
461 case CFXGA_MODE_800x600x16:
462 width = 800;
463 height = 600;
464 depth = 16;
465 break;
466 #ifdef ENABLE_8BIT_MODES
467 case CFXGA_MODE_640x480x8:
468 width = 640;
469 height = 480;
470 depth = 8;
471 break;
472 case CFXGA_MODE_800x600x8:
473 width = 800;
474 height = 600;
475 depth = 8;
476 break;
477 #endif
478 }
479
480 ri = &scr->scr_ri;
481 ri->ri_hw = (void *)scr;
482 ri->ri_bits = NULL;
483 ri->ri_depth = depth;
484 ri->ri_width = width;
485 ri->ri_height = height;
486 ri->ri_stride = width * depth / 8;
487 ri->ri_flg = 0;
488
489
490 if (depth == 16) {
491 ri->ri_rnum = 5;
492 ri->ri_rpos = 11;
493 ri->ri_gnum = 6;
494 ri->ri_gpos = 5;
495 ri->ri_bnum = 5;
496 ri->ri_bpos = 0;
497 }
498
499 if (type->nrows == 0)
500 rasops_init(ri, 100, 100);
501 else
502 rasops_init(ri, type->nrows, type->ncols);
503
504
505
506
507
508 scrsize = ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell);
509 scr->scr_mem = malloc(scrsize, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
510 if (scr->scr_mem == NULL) {
511 free(scr, M_DEVBUF);
512 return (ENOMEM);
513 }
514 bzero(scr->scr_mem, scrsize);
515
516 ri->ri_ops.copycols = cfxga_copycols;
517 ri->ri_ops.copyrows = cfxga_copyrows;
518 ri->ri_ops.erasecols = cfxga_erasecols;
519 ri->ri_ops.eraserows = cfxga_eraserows;
520 ri->ri_ops.putchar = cfxga_putchar;
521 ri->ri_do_cursor = cfxga_do_cursor;
522
523
524
525
526
527 if (type->nrows == 0) {
528 struct wsscreen_descr *wsd = (struct wsscreen_descr *)type;
529
530 wsd->nrows = ri->ri_rows;
531 wsd->ncols = ri->ri_cols;
532 bcopy(&ri->ri_ops, &sc->sc_ops, sizeof(sc->sc_ops));
533 wsd->fontwidth = ri->ri_font->fontwidth;
534 wsd->fontheight = ri->ri_font->fontheight;
535 wsd->capabilities = ri->ri_caps;
536 }
537
538 scr->scr_sc = sc;
539 LIST_INSERT_HEAD(&sc->sc_scr, scr, scr_link);
540 sc->sc_nscreens++;
541
542 ri->ri_ops.alloc_attr(ri, 0, 0, 0, attrp);
543
544 *cookiep = ri;
545 *curxp = *curyp = 0;
546
547 return (0);
548 }
549
550 void
551 cfxga_burner(void *v, u_int on, u_int flags)
552 {
553 struct cfxga_softc *sc = (void *)v;
554 u_int8_t mode;
555
556 mode = cfxga_read_1(sc, CFREG_MODE) & LCD_MODE_SWIVEL_BIT_0;
557
558 if (on)
559 cfxga_write_1(sc, CFREG_MODE, mode | MODE_CRT);
560 else
561 cfxga_write_1(sc, CFREG_MODE, mode | MODE_NO_DISPLAY);
562 }
563
564 void
565 cfxga_free_screen(void *v, void *cookie)
566 {
567 struct cfxga_softc *sc = v;
568 struct rasops_info *ri = cookie;
569 struct cfxga_screen *scr = ri->ri_hw;
570
571 LIST_REMOVE(scr, scr_link);
572 sc->sc_nscreens--;
573
574 if (scr == sc->sc_active) {
575 sc->sc_active = NULL;
576 cfxga_burner(sc, 0, 0);
577 }
578
579 free(scr->scr_mem, M_DEVBUF);
580 free(scr, M_DEVBUF);
581 }
582
583 int
584 cfxga_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
585 {
586 struct cfxga_softc *sc = v;
587 struct cfxga_screen *scr;
588 struct wsdisplay_fbinfo *wdf;
589 int mode;
590
591 switch (cmd) {
592 case WSDISPLAYIO_GTYPE:
593 *(u_int *)data = WSDISPLAY_TYPE_CFXGA;
594 break;
595
596 case WSDISPLAYIO_GINFO:
597 wdf = (struct wsdisplay_fbinfo *)data;
598 scr = sc->sc_active;
599 if (scr == NULL) {
600
601 wdf->height = wdf->width = wdf->depth = wdf->cmsize = 0;
602 } else {
603 wdf->height = scr->scr_ri.ri_height;
604 wdf->width = scr->scr_ri.ri_width;
605 wdf->depth = scr->scr_ri.ri_depth;
606 wdf->cmsize = scr->scr_ri.ri_depth <= 8 ?
607 (1 << scr->scr_ri.ri_depth) : 0;
608 }
609 break;
610
611 case WSDISPLAYIO_SMODE:
612 mode = *(u_int *)data;
613 if (mode == sc->sc_mode)
614 break;
615 switch (mode) {
616 case WSDISPLAYIO_MODE_EMUL:
617 cfxga_reset_and_repaint(sc);
618 break;
619 case WSDISPLAYIO_MODE_MAPPED:
620 break;
621 default:
622 return (EINVAL);
623 }
624 sc->sc_mode = mode;
625 break;
626
627
628 case WSDISPLAYIO_GVIDEO:
629 case WSDISPLAYIO_SVIDEO:
630 break;
631
632
633 case WSDISPLAYIO_GETCMAP:
634 case WSDISPLAYIO_PUTCMAP:
635 case WSDISPLAYIO_LINEBYTES:
636 case WSDISPLAYIO_GCURPOS:
637 case WSDISPLAYIO_SCURPOS:
638 case WSDISPLAYIO_GCURMAX:
639 case WSDISPLAYIO_GCURSOR:
640 case WSDISPLAYIO_SCURSOR:
641 default:
642 return (-1);
643 }
644
645 return (0);
646 }
647
648 paddr_t
649 cfxga_mmap(void *v, off_t off, int prot)
650 {
651 return (-1);
652 }
653
654 int
655 cfxga_show_screen(void *v, void *cookie, int waitok,
656 void (*cb)(void *, int, int), void *cbarg)
657 {
658 struct cfxga_softc *sc = v;
659 struct rasops_info *ri = cookie;
660 struct cfxga_screen *scr = ri->ri_hw, *old;
661
662 old = sc->sc_active;
663 if (old == scr)
664 return (0);
665
666 sc->sc_active = scr;
667 cfxga_reset_and_repaint(sc);
668
669 return (0);
670 }
671
672
673
674
675
676 void
677 cfxga_reset_video(struct cfxga_softc *sc)
678 {
679 struct cfxga_screen *scr = sc->sc_active;
680 struct rasops_info *ri;
681 #ifdef ENABLE_8BIT_MODES
682 const u_int8_t *cmap;
683 u_int i;
684 #endif
685
686
687
688
689
690
691 cfxga_write_2(sc, CFREG_REV, 0x80 | (CM_REGSEL << 8));
692 delay(25000);
693
694 cfxga_write_2(sc, CFREG_REV, 0 | (CM_MEMSEL << 8));
695 delay(25000);
696
697 cfxga_write_2(sc, CFREG_BITBLT_CONTROL, 0);
698 cfxga_stop_memory_blt(sc);
699 cfxga_write_1(sc, CFREG_MODE, 0);
700
701
702
703
704
705 cfxga_write_2(sc, CFREG_MEMCLK, MEMCLK_SRC_CLK3);
706 #if 0
707 cfxga_write_1(sc, CFREG_LCD_PCLK, LCD_PCLK_SRC_CLKI | LCD_PCLK_DIV_1);
708 cfxga_write_1(sc, CFREG_MPLUG_CLK,
709 MPLUG_PCLK_SRC_CLKI2 | MPLUG_PCLK_DIV_1);
710 #endif
711 cfxga_write_2(sc, CFREG_CRTTV_PCLK, CRT_PCLK_SRC_CLKI | CRT_PCLK_DIV_1);
712 cfxga_write_2(sc, CFREG_WSTATE, WSTATE_MCLK);
713
714
715 cfxga_write_2(sc, CFREG_MEMCNF,
716 MEMCNF_SDRAM_INIT | (DRAM_RFRSH_50MHZ << 8));
717 delay(250);
718 cfxga_write_2(sc, CFREG_DRAM_TIMING, DRAM_TIMING_50MHZ);
719
720
721
722
723 if (scr == NULL)
724 return;
725
726 ri = &scr->scr_ri;
727 switch (scr->scr_ri.ri_width) {
728 default:
729 case 640:
730 cfxga_write_1(sc, CFREG_CRT_HWIDTH, (640 / 8) - 1);
731
732 cfxga_write_2(sc, CFREG_CRT_HNDISP, 23 | (2 << 8));
733 cfxga_write_1(sc, CFREG_CRT_HPULSE, 4);
734 cfxga_write_2(sc, CFREG_CRT_VHEIGHT, 480 - 1);
735
736 cfxga_write_2(sc, CFREG_CRT_VNDISP, 39 | (8 << 8));
737 cfxga_write_1(sc, CFREG_CRT_VPULSE, 2);
738 break;
739 case 800:
740 cfxga_write_1(sc, CFREG_CRT_HWIDTH, (800 / 8) - 1);
741
742 cfxga_write_2(sc, CFREG_CRT_HNDISP, 27 | (2 << 8));
743 cfxga_write_1(sc, CFREG_CRT_HPULSE, 4);
744 cfxga_write_2(sc, CFREG_CRT_VHEIGHT, 600 - 1);
745
746 cfxga_write_2(sc, CFREG_CRT_VNDISP, 25 | (8 << 8));
747 cfxga_write_1(sc, CFREG_CRT_VPULSE, 2);
748 break;
749 }
750 cfxga_write_1(sc, CFREG_CRT_MODE,
751 ri->ri_depth == 16 ? CRT_MODE_16BPP : CRT_MODE_8BPP);
752 cfxga_write_2(sc, CFREG_CRT_START_LOW, 0);
753 cfxga_write_1(sc, CFREG_CRT_START_HIGH, 0);
754 cfxga_write_2(sc, CFREG_CRT_MEMORY, ri->ri_width * ri->ri_depth / 16);
755 cfxga_write_1(sc, CFREG_CRT_PANNING, 0);
756 cfxga_write_1(sc, CFREG_CRT_FIFO_THRESHOLD_HIGH, 0);
757 cfxga_write_1(sc, CFREG_CRT_FIFO_THRESHOLD_LOW, 0);
758 cfxga_write_1(sc, CFREG_CRT_CURSOR_CONTROL, CURSOR_INACTIVE);
759
760 #ifdef ENABLE_8BIT_MODES
761
762
763
764 if (ri->ri_depth == 8) {
765 #if 0
766
767 while ((cfxga_read_1(sc, CFREG_CRT_VNDISP) &
768 CRT_VNDISP_STATUS) == 0)
769 delay(1);
770 #endif
771 cfxga_write_1(sc, CFREG_LUT_MODE, LUT_CRT);
772 cfxga_write_1(sc, CFREG_LUT_ADDRESS, 0);
773 cmap = rasops_cmap;
774 for (i = 256 * 3; i != 0; i--)
775 cfxga_write_1(sc, CFREG_LUT_DATA, *cmap++ & 0xf0);
776 }
777 #endif
778
779 cfxga_write_1(sc, CFREG_TV_CONTROL,
780 TV_LUMINANCE_FILTER | TV_SVIDEO_OUTPUT | TV_NTSC_OUTPUT);
781
782 cfxga_write_1(sc, CFREG_POWER_CONF, POWERSAVE_MBO);
783 cfxga_write_1(sc, CFREG_WATCHDOG, 0);
784
785 cfxga_write_1(sc, CFREG_MODE, MODE_CRT);
786 delay(25000);
787 }
788
789 void
790 cfxga_reset_and_repaint(struct cfxga_softc *sc)
791 {
792 cfxga_reset_video(sc);
793
794 if (sc->sc_active != NULL)
795 cfxga_repaint_screen(sc->sc_active);
796 else
797 cfxga_burner(sc, 0, 0);
798 }
799
800
801
802
803 u_int
804 cfxga_wait(struct cfxga_softc *sc, u_int mask, u_int result)
805 {
806 u_int tries;
807
808 for (tries = 10000; tries != 0; tries--) {
809 if ((cfxga_read_1(sc, CFREG_BITBLT_CONTROL) & mask) == result)
810 break;
811 delay(10);
812 }
813
814 return (tries);
815 }
816
817
818
819
820
821 int
822 cfxga_synchronize(struct cfxga_softc *sc)
823 {
824
825 if (cfxga_wait(sc, BITBLT_ACTIVE, 0) == 0) {
826 DPRINTF(("%s: not ready\n", __func__));
827 if (ISSET(sc->sc_state, CS_RESET))
828 return (EAGAIN);
829 else {
830 DPRINTF(("%s: resetting...\n", sc->sc_dev.dv_xname));
831 SET(sc->sc_state, CS_RESET);
832 cfxga_reset_and_repaint(sc);
833 CLR(sc->sc_state, CS_RESET);
834 }
835 }
836 cfxga_stop_memory_blt(sc);
837 return (0);
838 }
839
840
841
842
843 int
844 cfxga_expand_char(struct cfxga_screen *scr, u_int uc, int x, int y, long attr)
845 {
846 struct cfxga_softc *sc = scr->scr_sc;
847 struct rasops_info *ri = &scr->scr_ri;
848 struct wsdisplay_font *font = ri->ri_font;
849 u_int pos, sts, fifo_avail, chunk;
850 u_int8_t *fontbits;
851 int bg, fg, ul;
852 u_int i;
853 int rc;
854
855 pos = (y * ri->ri_width + x) * ri->ri_depth / 8;
856 fontbits = (u_int8_t *)(font->data + (uc - font->firstchar) *
857 ri->ri_fontscale);
858 ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, &ul);
859
860
861 if ((rc = cfxga_synchronize(sc)) != 0)
862 return (rc);
863
864 cfxga_write_2(sc, CFREG_COLOR_EXPANSION,
865 ((font->fontwidth - 1) & 7) | (OP_COLOR_EXPANSION << 8));
866 cfxga_write_2(sc, CFREG_BITBLT_SRC_LOW, font->fontwidth <= 8 ? 0 : 1);
867 cfxga_write_2(sc, CFREG_BITBLT_SRC_HIGH, 0);
868 cfxga_write_2(sc, CFREG_BITBLT_DST_LOW, pos);
869 cfxga_write_2(sc, CFREG_BITBLT_DST_HIGH, pos >> 16);
870 cfxga_write_2(sc, CFREG_BITBLT_OFFSET,
871 ri->ri_width * ri->ri_depth / 16);
872 cfxga_write_2(sc, CFREG_BITBLT_WIDTH, font->fontwidth - 1);
873 cfxga_write_2(sc, CFREG_BITBLT_HEIGHT, font->fontheight - 1);
874 cfxga_write_2(sc, CFREG_BITBLT_FG, ri->ri_devcmap[fg]);
875 cfxga_write_2(sc, CFREG_BITBLT_BG, ri->ri_devcmap[bg]);
876 cfxga_write_2(sc, CFREG_BITBLT_CONTROL, BITBLT_ACTIVE |
877 (ri->ri_depth > 8 ? BITBLT_COLOR_16 : BITBLT_COLOR_8));
878
879 if (cfxga_wait(sc, BITBLT_ACTIVE, BITBLT_ACTIVE) == 0)
880 goto fail;
881 fifo_avail = 0;
882
883 for (i = font->fontheight; i != 0; i--) {
884
885
886
887
888 if (fifo_avail == 0) {
889 sts = cfxga_read_1(sc, CFREG_BITBLT_CONTROL);
890 if ((sts & BITBLT_FIFO_NOT_EMPTY) == 0)
891 fifo_avail = font->fontwidth <= 8 ? 2 : 1;
892 else if ((sts & BITBLT_FIFO_HALF_FULL) == 0)
893 fifo_avail = font->fontwidth <= 8 ? 1 : 0;
894 else {
895
896
897
898
899
900 if (cfxga_wait(sc, BITBLT_FIFO_FULL, 0) == 0)
901 goto fail;
902 }
903 }
904
905 if (font->fontwidth <= 8) {
906 chunk = *fontbits;
907 if (ul && i == 1)
908 chunk = 0xff;
909 } else {
910 chunk = *(u_int16_t *)fontbits;
911 if (ul && i == 1)
912 chunk = 0xffff;
913 }
914 cfxga_write_2(sc, CFREG_BITBLT_DATA, chunk);
915 fontbits += font->stride;
916 fifo_avail--;
917 }
918
919 return (0);
920
921 fail:
922 DPRINTF(("%s: abort\n", __func__));
923 cfxga_write_2(sc, CFREG_BITBLT_CONTROL, 0);
924 cfxga_stop_memory_blt(sc);
925 return (EINTR);
926 }
927
928
929
930
931
932
933
934 int
935 cfxga_repaint_screen(struct cfxga_screen *scr)
936 {
937 struct wsdisplay_charcell *cell = scr->scr_mem;
938 struct rasops_info *ri = &scr->scr_ri;
939 int x, y, cx, cy, lx, ly;
940 int fg, bg;
941 int rc;
942
943 cfxga_clear_screen(scr);
944
945 cx = ri->ri_font->fontwidth;
946 cy = ri->ri_font->fontheight;
947
948 for (ly = 0, y = ri->ri_yorigin; ly < ri->ri_rows; ly++, y += cy) {
949 for (lx = 0, x = ri->ri_xorigin; lx < ri->ri_cols;
950 lx++, x += cx) {
951 if (cell->uc == 0 || cell->uc == ' ') {
952 ri->ri_ops.unpack_attr(ri, cell->attr,
953 &fg, &bg, NULL);
954 rc = cfxga_solid_fill(scr, x, y, cx, cy,
955 ri->ri_devcmap[bg]);
956 } else {
957 rc = cfxga_expand_char(scr, cell->uc,
958 x, y, cell->attr);
959 }
960 cell++;
961 if (rc != 0)
962 return (rc);
963 }
964 }
965
966 return (0);
967 }
968
969
970
971
972 int
973 cfxga_solid_fill(struct cfxga_screen *scr, int x, int y, int cx, int cy,
974 int32_t srccolor)
975 {
976 struct cfxga_softc *sc = scr->scr_sc;
977 struct rasops_info *ri = &scr->scr_ri;
978 u_int pos;
979 int rc;
980
981 pos = (y * ri->ri_width + x) * ri->ri_depth / 8;
982
983
984 if ((rc = cfxga_synchronize(sc)) != 0)
985 return (rc);
986
987 cfxga_write_2(sc, CFREG_BITBLT_ROP, 0 | (OP_SOLID_FILL << 8));
988 cfxga_write_2(sc, CFREG_BITBLT_SRC_LOW, pos);
989 cfxga_write_2(sc, CFREG_BITBLT_SRC_HIGH, pos >> 16);
990 cfxga_write_2(sc, CFREG_BITBLT_DST_LOW, pos);
991 cfxga_write_2(sc, CFREG_BITBLT_DST_HIGH, pos >> 16);
992 cfxga_write_2(sc, CFREG_BITBLT_OFFSET,
993 ri->ri_width * ri->ri_depth / 16);
994 cfxga_write_2(sc, CFREG_BITBLT_WIDTH, cx - 1);
995 cfxga_write_2(sc, CFREG_BITBLT_HEIGHT, cy - 1);
996 cfxga_write_2(sc, CFREG_BITBLT_FG, (u_int16_t)srccolor);
997 cfxga_write_2(sc, CFREG_BITBLT_CONTROL, BITBLT_ACTIVE |
998 (ri->ri_depth > 8 ? BITBLT_COLOR_16 : BITBLT_COLOR_8));
999
1000 return (0);
1001 }
1002
1003
1004
1005
1006 int
1007 cfxga_standalone_rop(struct cfxga_screen *scr, u_int rop, int sx, int sy,
1008 int dx, int dy, int cx, int cy)
1009 {
1010 struct cfxga_softc *sc = scr->scr_sc;
1011 struct rasops_info *ri = &scr->scr_ri;
1012 u_int srcpos, dstpos;
1013 u_int opcode;
1014 int rc;
1015
1016 srcpos = (sy * ri->ri_width + sx) * ri->ri_depth / 8;
1017 dstpos = (dy * ri->ri_width + dx) * ri->ri_depth / 8;
1018
1019 if (dstpos <= srcpos)
1020 opcode = (OP_MOVE_POSITIVE_ROP << 8) | rop;
1021 else
1022 opcode = (OP_MOVE_NEGATIVE_ROP << 8) | rop;
1023
1024
1025 if ((rc = cfxga_synchronize(sc)) != 0)
1026 return (rc);
1027
1028 cfxga_write_2(sc, CFREG_BITBLT_ROP, opcode);
1029 cfxga_write_2(sc, CFREG_BITBLT_SRC_LOW, srcpos);
1030 cfxga_write_2(sc, CFREG_BITBLT_SRC_HIGH, srcpos >> 16);
1031 cfxga_write_2(sc, CFREG_BITBLT_DST_LOW, dstpos);
1032 cfxga_write_2(sc, CFREG_BITBLT_DST_HIGH, dstpos >> 16);
1033 cfxga_write_2(sc, CFREG_BITBLT_OFFSET,
1034 ri->ri_width * ri->ri_depth / 16);
1035 cfxga_write_2(sc, CFREG_BITBLT_WIDTH, cx - 1);
1036 cfxga_write_2(sc, CFREG_BITBLT_HEIGHT, cy - 1);
1037 cfxga_write_2(sc, CFREG_BITBLT_CONTROL, BITBLT_ACTIVE |
1038 (ri->ri_depth > 8 ? BITBLT_COLOR_16 : BITBLT_COLOR_8));
1039
1040 return (0);
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 void
1052 cfxga_copycols(void *cookie, int row, int src, int dst, int num)
1053 {
1054 struct rasops_info *ri = cookie;
1055 struct cfxga_screen *scr = ri->ri_hw;
1056 int sx, dx, y, cx, cy;
1057
1058
1059 ovbcopy(scr->scr_mem + row * ri->ri_cols + src,
1060 scr->scr_mem + row * ri->ri_cols + dst,
1061 num * sizeof(struct wsdisplay_charcell));
1062
1063 if (scr != scr->scr_sc->sc_active)
1064 return;
1065
1066 sx = src * ri->ri_font->fontwidth + ri->ri_xorigin;
1067 dx = dst * ri->ri_font->fontwidth + ri->ri_xorigin;
1068 y = row * ri->ri_font->fontheight + ri->ri_yorigin;
1069 cx = num * ri->ri_font->fontwidth;
1070 cy = ri->ri_font->fontheight;
1071 cfxga_standalone_rop(scr, ROP_SRC, sx, y, dx, y, cx, cy);
1072 }
1073
1074 void
1075 cfxga_copyrows(void *cookie, int src, int dst, int num)
1076 {
1077 struct rasops_info *ri = cookie;
1078 struct cfxga_screen *scr = ri->ri_hw;
1079 int x, sy, dy, cx, cy;
1080
1081
1082 ovbcopy(scr->scr_mem + src * ri->ri_cols,
1083 scr->scr_mem + dst * ri->ri_cols,
1084 num * ri->ri_cols * sizeof(struct wsdisplay_charcell));
1085
1086 if (scr != scr->scr_sc->sc_active)
1087 return;
1088
1089 x = ri->ri_xorigin;
1090 sy = src * ri->ri_font->fontheight + ri->ri_yorigin;
1091 dy = dst * ri->ri_font->fontheight + ri->ri_yorigin;
1092 cx = ri->ri_emuwidth;
1093 cy = num * ri->ri_font->fontheight;
1094 cfxga_standalone_rop(scr, ROP_SRC, x, sy, x, dy, cx, cy);
1095 }
1096
1097 void
1098 cfxga_do_cursor(struct rasops_info *ri)
1099 {
1100 struct cfxga_screen *scr = ri->ri_hw;
1101 int x, y, cx, cy;
1102
1103 if (scr != scr->scr_sc->sc_active)
1104 return;
1105
1106 x = ri->ri_ccol * ri->ri_font->fontwidth + ri->ri_xorigin;
1107 y = ri->ri_crow * ri->ri_font->fontheight + ri->ri_yorigin;
1108 cx = ri->ri_font->fontwidth;
1109 cy = ri->ri_font->fontheight;
1110 cfxga_standalone_rop(scr, ROP_ONES ^ ROP_SRC ,
1111 x, y, x, y, cx, cy);
1112 }
1113
1114 void
1115 cfxga_erasecols(void *cookie, int row, int col, int num, long attr)
1116 {
1117 struct rasops_info *ri = cookie;
1118 struct cfxga_screen *scr = ri->ri_hw;
1119 int fg, bg;
1120 int x, y, cx, cy;
1121
1122
1123 for (x = col; x < col + num; x++) {
1124 scr->scr_mem[row * ri->ri_cols + x].uc = 0;
1125 scr->scr_mem[row * ri->ri_cols + x].attr = attr;
1126 }
1127
1128 if (scr != scr->scr_sc->sc_active)
1129 return;
1130
1131 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
1132 x = col * ri->ri_font->fontwidth + ri->ri_xorigin;
1133 y = row * ri->ri_font->fontheight + ri->ri_yorigin;
1134 cx = num * ri->ri_font->fontwidth;
1135 cy = ri->ri_font->fontheight;
1136 cfxga_solid_fill(scr, x, y, cx, cy, ri->ri_devcmap[bg]);
1137 }
1138
1139 void
1140 cfxga_eraserows(void *cookie, int row, int num, long attr)
1141 {
1142 struct rasops_info *ri = cookie;
1143 struct cfxga_screen *scr = ri->ri_hw;
1144 int fg, bg;
1145 int x, y, cx, cy;
1146
1147
1148 for (x = 0; x < ri->ri_cols; x++) {
1149 scr->scr_mem[row * ri->ri_cols + x].uc = 0;
1150 scr->scr_mem[row * ri->ri_cols + x].attr = attr;
1151 }
1152 for (y = 1; y < num; y++)
1153 ovbcopy(scr->scr_mem + row * ri->ri_cols,
1154 scr->scr_mem + (row + y) * ri->ri_cols,
1155 ri->ri_cols * sizeof(struct wsdisplay_charcell));
1156
1157 if (scr != scr->scr_sc->sc_active)
1158 return;
1159
1160 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
1161 x = ri->ri_xorigin;
1162 y = row * ri->ri_font->fontheight + ri->ri_yorigin;
1163 cx = ri->ri_emuwidth;
1164 cy = num * ri->ri_font->fontheight;
1165 cfxga_solid_fill(scr, x, y, cx, cy, ri->ri_devcmap[bg]);
1166 }
1167
1168 void
1169 cfxga_putchar(void *cookie, int row, int col, u_int uc, long attr)
1170 {
1171 struct rasops_info *ri = cookie;
1172 struct cfxga_screen *scr = ri->ri_hw;
1173 int x, y;
1174
1175 scr->scr_mem[row * ri->ri_cols + col].uc = uc;
1176 scr->scr_mem[row * ri->ri_cols + col].attr = attr;
1177
1178 if (scr != scr->scr_sc->sc_active)
1179 return;
1180
1181 x = col * ri->ri_font->fontwidth + ri->ri_xorigin;
1182 y = row * ri->ri_font->fontheight + ri->ri_yorigin;
1183
1184 if (uc == ' ') {
1185 int cx, cy, fg, bg;
1186
1187 ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
1188 cx = ri->ri_font->fontwidth;
1189 cy = ri->ri_font->fontheight;
1190 cfxga_solid_fill(scr, x, y, cx, cy, ri->ri_devcmap[bg]);
1191 } else {
1192 cfxga_expand_char(scr, uc, x, y, attr);
1193 }
1194 }