Annotation of sys/arch/alpha/tc/cfb.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cfb.c,v 1.18 2006/11/29 12:13:51 miod Exp $ */
2: /* $NetBSD: cfb.c,v 1.7 1996/12/05 01:39:39 cgd Exp $ */
3:
4: /*
5: * Copyright (c) 1995, 1996 Carnegie-Mellon University.
6: * All rights reserved.
7: *
8: * Author: Chris G. Demetriou
9: *
10: * Permission to use, copy, modify and distribute this software and
11: * its documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33: #include <sys/kernel.h>
34: #include <sys/device.h>
35: #include <sys/malloc.h>
36: #include <sys/buf.h>
37: #include <sys/conf.h>
38: #include <sys/ioctl.h>
39:
40: #include <uvm/uvm_extern.h>
41:
42: #include <machine/bus.h>
43: #include <machine/intr.h>
44:
45: #include <dev/tc/tcvar.h>
46: #include <machine/cfbreg.h>
47: #include <alpha/tc/cfbvar.h>
48:
49: #include <dev/rcons/raster.h>
50: #include <dev/wscons/wscons_raster.h>
51: #include <dev/wscons/wsdisplayvar.h>
52: #include <machine/fbio.h>
53:
54: #include <machine/autoconf.h>
55: #include <machine/pte.h>
56:
57: int cfbmatch(struct device *, void *, void *);
58: void cfbattach(struct device *, struct device *, void *);
59:
60: struct cfattach cfb_ca = {
61: sizeof(struct cfb_softc), cfbmatch, cfbattach,
62: };
63:
64: struct cfdriver cfb_cd = {
65: NULL, "cfb", DV_DULL,
66: };
67:
68: void cfb_getdevconfig(tc_addr_t dense_addr, struct cfb_devconfig *dc);
69: struct cfb_devconfig cfb_console_dc;
70: tc_addr_t cfb_consaddr;
71:
72: struct wsdisplay_emulops cfb_emulfuncs = {
73: rcons_cursor, /* could use hardware cursor; punt */
74: rcons_mapchar,
75: rcons_putchar,
76: rcons_copycols,
77: rcons_erasecols,
78: rcons_copyrows,
79: rcons_eraserows,
80: rcons_alloc_attr
81: };
82:
83: struct wsscreen_descr cfb_stdscreen = {
84: "std",
85: 0, 0, /* will be filled in -- XXX shouldn't, it's global */
86: &cfb_emulfuncs,
87: 0, 0
88: };
89:
90: const struct wsscreen_descr *_cfb_scrlist[] = {
91: &cfb_stdscreen,
92: /* XXX other formats, graphics screen? */
93: };
94:
95: struct wsscreen_list cfb_screenlist = {
96: sizeof(_cfb_scrlist) / sizeof(struct wsscreen_descr *), _cfb_scrlist
97: };
98:
99: int cfbioctl(void *, u_long, caddr_t, int, struct proc *);
100: paddr_t cfbmmap(void *, off_t, int);
101:
102: int cfbintr(void *);
103: static int cfb_alloc_screen(void *, const struct wsscreen_descr *,
104: void **, int *, int *, long *);
105: static void cfb_free_screen(void *, void *);
106: static int cfb_show_screen(void *, void *, int,
107: void (*) (void *, int, int), void *);
108:
109: struct wsdisplay_accessops cfb_accessops = {
110: cfbioctl,
111: cfbmmap,
112: cfb_alloc_screen,
113: cfb_free_screen,
114: cfb_show_screen,
115: };
116:
117: int
118: cfbmatch(parent, match, aux)
119: struct device *parent;
120: void *match;
121: void *aux;
122: {
123: struct tc_attach_args *ta = aux;
124:
125: if (strncmp("PMAG-BA ", ta->ta_modname, TC_ROM_LLEN) != 0)
126: return (0);
127:
128: return (10);
129: }
130:
131: void
132: cfb_getdevconfig(dense_addr, dc)
133: tc_addr_t dense_addr;
134: struct cfb_devconfig *dc;
135: {
136: struct raster *rap;
137: struct rcons *rcp;
138: char *ramdacregp;
139: int i;
140:
141: dc->dc_vaddr = dense_addr;
142: dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
143: dc->dc_size = CFB_SIZE;
144:
145: ramdacregp = (char *)dc->dc_vaddr + CFB_RAMDAC_OFFSET;
146:
147: dc->dc_wid = 1024;
148: dc->dc_ht = 864;
149: dc->dc_depth = 8; /* 8 plane */
150: dc->dc_rowbytes = dc->dc_wid * (dc->dc_depth / 8);
151:
152: dc->dc_videobase = dc->dc_vaddr + CFB_FB_OFFSET;
153:
154: /* Initialize the RAMDAC/colormap */
155: /* start XXX XXX XXX */
156: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_ADDRLOW)) = 0;
157: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_ADDRHIGH)) = 0;
158: tc_wmb();
159: for (i = 0; i < 256; i++) {
160: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_CMAPDATA)) =
161: i ? 0xff : 0;
162: tc_wmb();
163: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_CMAPDATA)) =
164: i ? 0xff : 0;
165: tc_wmb();
166: (*(volatile u_int32_t *)(ramdacregp + CFB_RAMDAC_CMAPDATA)) =
167: i ? 0xff : 0;
168: tc_wmb();
169: }
170: /* end XXX XXX XXX */
171:
172: /* clear the screen */
173: for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
174: *(u_int32_t *)(dc->dc_videobase + i) = 0x00000000;
175:
176: rap = &dc->dc_raster;
177: rap->width = dc->dc_wid;
178: rap->height = dc->dc_ht;
179: rap->depth = 8;
180: rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
181: rap->pixels = (u_int32_t *)dc->dc_videobase;
182:
183: /* initialize the raster console blitter */
184: rcp = &dc->dc_rcons;
185: rcp->rc_sp = rap;
186: rcp->rc_crow = rcp->rc_ccol = -1;
187: rcp->rc_crowp = &rcp->rc_crow;
188: rcp->rc_ccolp = &rcp->rc_ccol;
189: rcons_init(rcp, 34, 80);
190:
191: cfb_stdscreen.nrows = dc->dc_rcons.rc_maxrow;
192: cfb_stdscreen.ncols = dc->dc_rcons.rc_maxcol;
193: }
194:
195: void
196: cfbattach(parent, self, aux)
197: struct device *parent, *self;
198: void *aux;
199: {
200: struct cfb_softc *sc = (struct cfb_softc *)self;
201: struct tc_attach_args *ta = aux;
202: struct wsemuldisplaydev_attach_args waa;
203: int console;
204:
205: console = (ta->ta_addr == cfb_consaddr);
206: if (console) {
207: sc->sc_dc = &cfb_console_dc;
208: sc->nscreens = 1;
209: } else {
210: sc->sc_dc = (struct cfb_devconfig *)
211: malloc(sizeof(struct cfb_devconfig), M_DEVBUF, M_WAITOK);
212: cfb_getdevconfig(ta->ta_addr, sc->sc_dc);
213: }
214: if (sc->sc_dc->dc_vaddr == NULL) {
215: printf(": couldn't map memory space; punt!\n");
216: return;
217: }
218: printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
219: sc->sc_dc->dc_depth);
220:
221: /* Establish an interrupt handler, and clear any pending interrupts */
222: tc_intr_establish(parent, ta->ta_cookie, TC_IPL_TTY, cfbintr, sc);
223: *(volatile u_int32_t *)(sc->sc_dc->dc_vaddr + CFB_IREQCTRL_OFFSET) = 0;
224:
225: /* initialize the raster */
226: waa.console = console;
227: waa.scrdata = &cfb_screenlist;
228: waa.accessops = &cfb_accessops;
229: waa.accesscookie = sc;
230: waa.defaultscreens = 0;
231:
232: config_found(self, &waa, wsemuldisplaydevprint);
233: }
234:
235: int
236: cfbioctl(v, cmd, data, flag, p)
237: void *v;
238: u_long cmd;
239: caddr_t data;
240: int flag;
241: struct proc *p;
242: {
243: struct cfb_softc *sc = v;
244: struct cfb_devconfig *dc = sc->sc_dc;
245:
246: switch (cmd) {
247: case FBIOGTYPE:
248: #define fbt ((struct fbtype *)data)
249: fbt->fb_type = FBTYPE_CFB;
250: fbt->fb_height = sc->sc_dc->dc_ht;
251: fbt->fb_width = sc->sc_dc->dc_wid;
252: fbt->fb_depth = sc->sc_dc->dc_depth;
253: fbt->fb_cmsize = 256; /* XXX ??? */
254: fbt->fb_size = sc->sc_dc->dc_size;
255: #undef fbt
256: return (0);
257:
258: #if 0
259: case FBIOPUTCMAP:
260: return (*tgar->tgar_set_cmap)(dc, (struct fbcmap *)data);
261:
262: case FBIOGETCMAP:
263: return (*tgar->tgar_get_cmap)(dc, (struct fbcmap *)data);
264: #endif
265:
266: case FBIOGATTR:
267: return (ENOTTY); /* XXX ? */
268:
269: #if 0
270: case FBIOSVIDEO:
271: if (*(int *)data == FBVIDEO_OFF)
272: cfb_blank(sc->sc_dc);
273: else
274: cfb_unblank(sc->sc_dc);
275: return (0);
276: #endif
277:
278: case FBIOGVIDEO:
279: *(int *)data = dc->dc_blanked ? FBVIDEO_OFF : FBVIDEO_ON;
280: return (0);
281:
282: #if 0
283: case FBIOSCURSOR:
284: return (*tgar->tgar_set_cursor)(dc, (struct fbcursor *)data);
285:
286: case FBIOGCURSOR:
287: return (*tgar->tgar_get_cursor)(dc, (struct fbcursor *)data);
288:
289: case FBIOSCURPOS:
290: return (*tgar->tgar_set_curpos)(dc, (struct fbcurpos *)data);
291:
292: case FBIOGCURPOS:
293: return (*tgar->tgar_get_curpos)(dc, (struct fbcurpos *)data);
294:
295: case FBIOGCURMAX:
296: return (*tgar->tgar_get_curmax)(dc, (struct fbcurpos *)data);
297: #endif
298: }
299: return (-1);
300: }
301:
302: paddr_t
303: cfbmmap(v, offset, prot)
304: void *v;
305: off_t offset;
306: int prot;
307: {
308: struct cfb_softc *sc = v;
309:
310: if (offset > CFB_SIZE)
311: return (-1);
312: return atop(sc->sc_dc->dc_paddr + offset);
313: }
314:
315: int
316: cfbintr(v)
317: void *v;
318: {
319: struct cfb_softc *sc = v;
320:
321: *(volatile u_int32_t *)(sc->sc_dc->dc_vaddr + CFB_IREQCTRL_OFFSET) = 0;
322:
323: return (1);
324: }
325:
326: int
327: cfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
328: void *v;
329: const struct wsscreen_descr *type;
330: void **cookiep;
331: int *curxp, *curyp;
332: long *attrp;
333: {
334: struct cfb_softc *sc = v;
335: long defattr;
336:
337: if (sc->nscreens > 0)
338: return (ENOMEM);
339:
340: *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
341: *curxp = 0;
342: *curyp = 0;
343: rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
344: *attrp = defattr;
345: sc->nscreens++;
346: return(0);
347: }
348:
349: void
350: cfb_free_screen(v, cookie)
351: void *v;
352: void *cookie;
353: {
354: struct cfb_softc *sc = v;
355:
356: if (sc->sc_dc == &cfb_console_dc)
357: panic("cfb_free_screen: console");
358:
359: sc->nscreens--;
360: }
361:
362: int
363: cfb_show_screen(v, cookie, waitok, cb, cbarg)
364: void *v;
365: void *cookie;
366: int waitok;
367: void (*cb)(void *, int, int);
368: void *cbarg;
369: {
370: return (0);
371: }
372:
373: #if 0
374: int
375: cfb_cnattach(addr)
376: tc_addr_t addr;
377: {
378: struct cfb_devconfig *dc = &cfb_console_dc;
379: long defattr;
380:
381: cfb_getdevconfig(addr, dcp);
382:
383: rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr);
384:
385: wsdisplay_cnattach(&cfb_stdscreen, &dcp->dc_rcons,
386: 0,0, defattr;);
387:
388: cfb_consaddr = addr;
389: return (0);
390: }
391: #endif
CVSweb