This source file includes following definitions.
- cgtwelvematch
- cgtwelveattach
- cgtwelve_ioctl
- cgtwelve_reset
- cgtwelve_mmap
- cgtwelve_alloc_screen
- cgtwelve_free_screen
- cgtwelve_show_screen
- cgtwelve_ramdac_wraddr
- cgtwelve_prom
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/buf.h>
52 #include <sys/device.h>
53 #include <sys/ioctl.h>
54 #include <sys/conf.h>
55
56 #include <uvm/uvm_extern.h>
57
58 #include <machine/autoconf.h>
59 #include <machine/bus.h>
60 #include <machine/pmap.h>
61 #include <machine/cpu.h>
62 #include <machine/conf.h>
63
64 #include <dev/wscons/wsconsio.h>
65 #include <dev/wscons/wsdisplayvar.h>
66 #include <dev/rasops/rasops.h>
67 #include <machine/fbvar.h>
68
69 #include <dev/sbus/sbusvar.h>
70
71 #include <dev/sbus/cgtwelvereg.h>
72
73 #include <dev/cons.h>
74
75
76 struct cgtwelve_softc {
77 struct sunfb sc_sunfb;
78 bus_space_tag_t sc_bustag;
79 bus_addr_t sc_paddr;
80
81 volatile struct cgtwelve_dpu *sc_dpu;
82 volatile struct cgtwelve_apu *sc_apu;
83 volatile struct cgtwelve_dac *sc_ramdac;
84 volatile u_char *sc_overlay;
85 volatile u_long *sc_inten;
86
87 int sc_highres;
88 int sc_nscreens;
89 };
90
91 int cgtwelve_ioctl(void *, u_long, caddr_t, int, struct proc *);
92 int cgtwelve_alloc_screen(void *, const struct wsscreen_descr *, void **,
93 int *, int *, long *);
94 void cgtwelve_free_screen(void *, void *);
95 int cgtwelve_show_screen(void *, void *, int, void (*cb)(void *, int, int),
96 void *);
97 paddr_t cgtwelve_mmap(void *, off_t, int);
98 void cgtwelve_reset(struct cgtwelve_softc *, int);
99 void cgtwelve_prom(void *);
100
101 static __inline__ void cgtwelve_ramdac_wraddr(struct cgtwelve_softc *sc,
102 u_int32_t addr);
103
104 struct wsdisplay_accessops cgtwelve_accessops = {
105 cgtwelve_ioctl,
106 cgtwelve_mmap,
107 cgtwelve_alloc_screen,
108 cgtwelve_free_screen,
109 cgtwelve_show_screen,
110 NULL,
111 NULL,
112 NULL,
113 NULL
114 };
115
116 int cgtwelvematch(struct device *, void *, void *);
117 void cgtwelveattach(struct device *, struct device *, void *);
118
119 struct cfattach cgtwelve_ca = {
120 sizeof(struct cgtwelve_softc), cgtwelvematch, cgtwelveattach
121 };
122
123 struct cfdriver cgtwelve_cd = {
124 NULL, "cgtwelve", DV_DULL
125 };
126
127
128
129
130
131 int
132 cgtwelvematch(struct device *parent, void *vcf, void *aux)
133 {
134 struct cfdata *cf = vcf;
135 struct sbus_attach_args *sa = aux;
136
137 if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0)
138 return (0);
139
140 return (1);
141 }
142
143
144
145
146 void
147 cgtwelveattach(struct device *parent, struct device *self, void *args)
148 {
149 struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self;
150 struct sbus_attach_args *sa = args;
151 bus_space_tag_t bt;
152 bus_space_handle_t bh;
153 int node, isconsole = 0;
154 char *ps;
155
156 bt = sa->sa_bustag;
157 node = sa->sa_node;
158
159 printf(": %s", getpropstring(node, "model"));
160 ps = getpropstring(node, "dev_id");
161 if (*ps != '\0')
162 printf(" (%s)", ps);
163 printf("\n");
164
165 isconsole = node == fbnode;
166
167 if (sa->sa_nreg == 0) {
168 printf("%s: no SBus registers!\n", self->dv_xname);
169 return;
170 }
171
172 sc->sc_bustag = bt;
173
174
175
176
177 if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
178 CG12_OFF_DPU, sizeof(struct cgtwelve_dpu),
179 BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
180 printf("%s: can't map DPU registers\n", self->dv_xname);
181 return;
182 }
183 sc->sc_dpu = bus_space_vaddr(bt, bh);
184 if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
185 CG12_OFF_APU, sizeof(struct cgtwelve_apu),
186 BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
187 printf("%s: can't map APU registers\n", self->dv_xname);
188 return;
189 }
190 sc->sc_apu = bus_space_vaddr(bt, bh);
191 if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
192 CG12_OFF_DAC, sizeof(struct cgtwelve_dac),
193 BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
194 printf("%s: can't map RAMDAC registers\n", self->dv_xname);
195 return;
196 }
197 sc->sc_ramdac = bus_space_vaddr(bt, bh);
198
199
200
201
202
203 fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT,
204 node, 0);
205 sc->sc_sunfb.sf_depth = 1;
206 sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8;
207 sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height *
208 sc->sc_sunfb.sf_linebytes;
209
210 sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR;
211
212
213
214
215 if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
216 (sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0),
217 round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR :
218 CG12_SIZE_OVERLAY), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
219 printf("%s: can't map overlay plane\n", self->dv_xname);
220 return;
221 }
222 sc->sc_overlay = bus_space_vaddr(bt, bh);
223 if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
224 (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN),
225 round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR :
226 CG12_SIZE_COLOR24), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
227 printf("%s: can't map color plane\n", self->dv_xname);
228 return;
229 }
230 sc->sc_inten = bus_space_vaddr(bt, bh);
231 sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset +
232 (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN));
233
234
235 sc->sc_sunfb.sf_depth = 0;
236 cgtwelve_reset(sc, 1);
237
238 sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay;
239 sc->sc_sunfb.sf_ro.ri_hw = sc;
240 fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
241
242 if (isconsole) {
243 fbwscons_console_init(&sc->sc_sunfb, -1);
244 shutdownhook_establish(cgtwelve_prom, sc);
245 }
246
247 printf("%s: %dx%d", self->dv_xname,
248 sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
249 ps = getpropstring(node, "ucoderev");
250 if (*ps != '\0')
251 printf(", microcode rev. %s", ps);
252 printf("\n");
253
254 fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole);
255 }
256
257 int
258 cgtwelve_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
259 {
260 struct cgtwelve_softc *sc = dev;
261 struct wsdisplay_fbinfo *wdf;
262
263
264
265
266
267
268 switch (cmd) {
269 case WSDISPLAYIO_GTYPE:
270 *(u_int *)data = WSDISPLAY_TYPE_SUNCG12;
271 break;
272 case WSDISPLAYIO_GINFO:
273 wdf = (struct wsdisplay_fbinfo *)data;
274 wdf->height = sc->sc_sunfb.sf_height;
275 wdf->width = sc->sc_sunfb.sf_width;
276 wdf->depth = 32;
277 wdf->cmsize = 0;
278 break;
279 case WSDISPLAYIO_GETSUPPORTEDDEPTH:
280 *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
281 break;
282 case WSDISPLAYIO_LINEBYTES:
283 *(u_int *)data = sc->sc_sunfb.sf_linebytes * 32;
284 break;
285
286 case WSDISPLAYIO_GETCMAP:
287 case WSDISPLAYIO_PUTCMAP:
288 break;
289
290 case WSDISPLAYIO_SMODE:
291 if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
292
293 cgtwelve_reset(sc, 1);
294 } else {
295
296 cgtwelve_reset(sc, 32);
297 }
298 break;
299
300 case WSDISPLAYIO_SVIDEO:
301 case WSDISPLAYIO_GVIDEO:
302 break;
303
304 default:
305 return (-1);
306 }
307
308 return (0);
309 }
310
311
312
313
314 void
315 cgtwelve_reset(struct cgtwelve_softc *sc, int depth)
316 {
317 u_int32_t c;
318
319 if (sc->sc_sunfb.sf_depth != depth) {
320 if (depth == 1) {
321
322
323
324 sc->sc_apu->hpage = sc->sc_highres ?
325 CG12_HPAGE_ENABLE_HR : CG12_HPAGE_ENABLE;
326 sc->sc_apu->haccess = CG12_HACCESS_ENABLE;
327 sc->sc_dpu->pln_sl_host = CG12_PLN_SL_ENABLE;
328 sc->sc_dpu->pln_rd_msk_host = CG12_PLN_RD_ENABLE;
329 sc->sc_dpu->pln_wr_msk_host = CG12_PLN_WR_ENABLE;
330
331 memset((void *)sc->sc_overlay, 0xff, sc->sc_highres ?
332 CG12_SIZE_ENABLE_HR : CG12_SIZE_ENABLE);
333
334
335
336
337 sc->sc_apu->hpage = sc->sc_highres ?
338 CG12_HPAGE_OVERLAY_HR : CG12_HPAGE_OVERLAY;
339 sc->sc_apu->haccess = CG12_HACCESS_OVERLAY;
340 sc->sc_dpu->pln_sl_host = CG12_PLN_SL_OVERLAY;
341 sc->sc_dpu->pln_rd_msk_host = CG12_PLN_RD_OVERLAY;
342 sc->sc_dpu->pln_wr_msk_host = CG12_PLN_WR_OVERLAY;
343
344
345
346
347
348
349 cgtwelve_ramdac_wraddr(sc, 0);
350 sc->sc_ramdac->color = 0x00000000;
351 for (c = 1; c < 256; c++)
352 sc->sc_ramdac->color = 0x00ffffff;
353 } else {
354
355
356
357 sc->sc_apu->hpage = sc->sc_highres ?
358 CG12_HPAGE_OVERLAY_HR : CG12_HPAGE_OVERLAY;
359 sc->sc_apu->haccess = CG12_HACCESS_OVERLAY;
360 sc->sc_dpu->pln_sl_host = CG12_PLN_SL_OVERLAY;
361 sc->sc_dpu->pln_rd_msk_host = CG12_PLN_RD_OVERLAY;
362 sc->sc_dpu->pln_wr_msk_host = CG12_PLN_WR_OVERLAY;
363
364
365
366
367
368
369
370
371 bzero((void *)sc->sc_overlay, sc->sc_highres ?
372 CG12_SIZE_OVERLAY_HR : CG12_SIZE_OVERLAY);
373
374
375
376
377 sc->sc_apu->hpage = sc->sc_highres ?
378 CG12_HPAGE_ENABLE_HR : CG12_HPAGE_ENABLE;
379 sc->sc_apu->haccess = CG12_HACCESS_ENABLE;
380 sc->sc_dpu->pln_sl_host = CG12_PLN_SL_ENABLE;
381 sc->sc_dpu->pln_rd_msk_host = CG12_PLN_RD_ENABLE;
382 sc->sc_dpu->pln_wr_msk_host = CG12_PLN_WR_ENABLE;
383
384 bzero((void *)sc->sc_overlay, sc->sc_highres ?
385 CG12_SIZE_ENABLE_HR : CG12_SIZE_ENABLE);
386
387
388
389
390 sc->sc_apu->hpage = sc->sc_highres ?
391 CG12_HPAGE_24BIT_HR : CG12_HPAGE_24BIT;
392 sc->sc_apu->haccess = CG12_HACCESS_24BIT;
393 sc->sc_dpu->pln_sl_host = CG12_PLN_SL_24BIT;
394 sc->sc_dpu->pln_rd_msk_host = CG12_PLN_RD_24BIT;
395 sc->sc_dpu->pln_wr_msk_host = CG12_PLN_WR_24BIT;
396
397 memset((void *)sc->sc_inten, 0x00ffffff,
398 sc->sc_highres ?
399 CG12_SIZE_COLOR24_HR : CG12_SIZE_COLOR24);
400
401
402
403
404 cgtwelve_ramdac_wraddr(sc, 0);
405 for (c = 0; c < 256; c++)
406 sc->sc_ramdac->color = c | (c << 8) | (c << 16);
407 }
408 }
409
410 sc->sc_sunfb.sf_depth = depth;
411 }
412
413
414
415
416
417 paddr_t
418 cgtwelve_mmap(void *v, off_t offset, int prot)
419 {
420 struct cgtwelve_softc *sc = v;
421
422 if (offset & PGOFSET || offset < 0)
423 return (-1);
424
425
426
427
428
429 if (offset < sc->sc_sunfb.sf_fbsize * 32) {
430 return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr, offset,
431 prot, BUS_SPACE_MAP_LINEAR));
432 }
433
434 return (-1);
435 }
436
437 int
438 cgtwelve_alloc_screen(void *v, const struct wsscreen_descr *type,
439 void **cookiep, int *curxp, int *curyp, long *attrp)
440 {
441 struct cgtwelve_softc *sc = v;
442
443 if (sc->sc_nscreens > 0)
444 return (ENOMEM);
445
446 *cookiep = &sc->sc_sunfb.sf_ro;
447 *curyp = 0;
448 *curxp = 0;
449 sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
450 0, 0, 0, attrp);
451 sc->sc_nscreens++;
452 return (0);
453 }
454
455 void
456 cgtwelve_free_screen(void *v, void *cookie)
457 {
458 struct cgtwelve_softc *sc = v;
459
460 sc->sc_nscreens--;
461 }
462
463 int
464 cgtwelve_show_screen(void *v, void *cookie, int waitok,
465 void (*cb)(void *, int, int), void *cbarg)
466 {
467 return (0);
468 }
469
470
471
472
473
474 static __inline__ void
475 cgtwelve_ramdac_wraddr(struct cgtwelve_softc *sc, u_int32_t addr)
476 {
477 sc->sc_ramdac->addr_lo = (addr & 0xff);
478 sc->sc_ramdac->addr_hi = ((addr >> 8) & 0xff);
479 }
480
481
482
483
484
485 void
486 cgtwelve_prom(void *v)
487 {
488 struct cgtwelve_softc *sc = v;
489 extern struct consdev consdev_prom;
490
491 if (sc->sc_sunfb.sf_depth != 1) {
492 cgtwelve_reset(sc, 1);
493
494
495
496
497
498 cn_tab = &consdev_prom;
499 }
500 }