Annotation of sys/arch/macppc/pci/vgafb.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: vgafb.c,v 1.33 2006/12/17 22:18:14 miod Exp $ */
2: /* $NetBSD: vga.c,v 1.3 1996/12/02 22:24:54 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/buf.h>
36:
37: #include <uvm/uvm_extern.h>
38:
39: #include <machine/bus.h>
40:
41: #include <dev/cons.h>
42: #include <dev/ofw/openfirm.h>
43: #include <macppc/macppc/ofw_machdep.h>
44:
45: #include <dev/wscons/wsconsio.h>
46: #include <dev/wscons/wsdisplayvar.h>
47: #include <dev/rasops/rasops.h>
48: #include <dev/wsfont/wsfont.h>
49:
50: #include <macppc/pci/vgafbvar.h>
51:
52: struct cfdriver vgafb_cd = {
53: NULL, "vgafb", DV_DULL,
54: };
55:
56: void vgafb_setcolor(struct vgafb_config *vc, unsigned int index,
57: u_int8_t r, u_int8_t g, u_int8_t b);
58: void vgafb_restore_default_colors(struct vgafb_config *vc);
59:
60: struct vgafb_devconfig {
61: struct rasops_info dc_rinfo; /* raster display data */
62: int dc_blanked; /* currently had video disabled */
63: };
64:
65: struct vgafb_devconfig vgafb_console_dc;
66:
67: struct wsscreen_descr vgafb_stdscreen = {
68: "std",
69: 0, 0, /* will be filled in -- XXX shouldn't, it's global */
70: 0,
71: 0, 0,
72: WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
73: WSSCREEN_REVERSE | WSSCREEN_WSCOLORS
74: };
75: const struct wsscreen_descr *vgafb_scrlist[] = {
76: &vgafb_stdscreen,
77: /* XXX other formats, graphics screen? */
78: };
79:
80: struct wsscreen_list vgafb_screenlist = {
81: sizeof(vgafb_scrlist) / sizeof(struct wsscreen_descr *), vgafb_scrlist
82: };
83:
84: struct wsdisplay_accessops vgafb_accessops = {
85: vgafb_ioctl,
86: vgafb_mmap,
87: vgafb_alloc_screen,
88: vgafb_free_screen,
89: vgafb_show_screen,
90: NULL, /* load_font */
91: NULL, /* scrollback */
92: NULL, /* getchar */
93: vgafb_burn, /* burner */
94: };
95:
96: int vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm);
97: int vgafb_putcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm);
98:
99: #define FONT_WIDTH 8
100: #define FONT_HEIGHT 16
101:
102: #ifdef APERTURE
103: extern int allowaperture;
104: #endif
105:
106: /*
107: * The following functions implement back-end configuration grabbing
108: * and attachment.
109: */
110: int
111: vgafb_common_probe(bus_space_tag_t iot, bus_space_tag_t memt, u_int32_t iobase,
112: size_t iosize, u_int32_t membase, size_t memsize, u_int32_t mmiobase,
113: size_t mmiosize)
114: {
115: bus_space_handle_t ioh_b, ioh_c, ioh_d, memh, mmioh;
116: int gotio_b, gotio_c, gotio_d, gotmem, gotmmio, rv;
117:
118: gotio_b = gotio_c = gotio_d = gotmem = gotmmio = rv = 0;
119:
120: if (iosize != 0) {
121: if (bus_space_map(iot, iobase+0x3b0, 0xc, 0, &ioh_b))
122: goto bad;
123: gotio_b = 1;
124: if (bus_space_map(iot, iobase+0x3c0, 0x10, 0, &ioh_c))
125: goto bad;
126: gotio_c = 1;
127: if (bus_space_map(iot, iobase+0x3d0, 0x10, 0, &ioh_d))
128: goto bad;
129: gotio_d = 1;
130: }
131: if (mmiosize != 0) {
132: if (bus_space_map(iot, mmiobase, mmiosize, 0, &mmioh))
133: goto bad;
134: gotmmio = 1;
135: }
136:
137: rv = 1;
138:
139: bad:
140: if (gotio_b)
141: bus_space_unmap(iot, ioh_b, 0xc);
142: if (gotio_c)
143: bus_space_unmap(iot, ioh_c, 0x10);
144: if (gotio_d)
145: bus_space_unmap(iot, ioh_d, 0x10);
146: if (gotmmio)
147: bus_space_unmap(memt, mmioh, mmiosize);
148: if (gotmem)
149: bus_space_unmap(memt, memh, memsize);
150:
151: return (rv);
152: }
153:
154: void
155: vgafb_common_setup(bus_space_tag_t iot, bus_space_tag_t memt,
156: struct vgafb_config *vc, u_int32_t iobase, size_t iosize,
157: u_int32_t membase, size_t memsize, u_int32_t mmiobase, size_t mmiosize)
158: {
159: vc->vc_iot = iot;
160: vc->vc_memt = memt;
161: vc->vc_paddr = membase;
162:
163: if (iosize != 0) {
164: if (bus_space_map(vc->vc_iot, iobase+0x3b0, 0xc, 0, &vc->vc_ioh_b))
165: panic("vgafb_common_setup: couldn't map io b");
166: if (bus_space_map(vc->vc_iot, iobase+0x3c0, 0x10, 0, &vc->vc_ioh_c))
167: panic("vgafb_common_setup: couldn't map io c");
168: if (bus_space_map(vc->vc_iot, iobase+0x3d0, 0x10, 0, &vc->vc_ioh_d))
169: panic("vgafb_common_setup: couldn't map io d");
170: }
171: if (mmiosize != 0)
172: if (bus_space_map(vc->vc_memt, mmiobase, mmiosize, 0,
173: &vc->vc_mmioh))
174: panic("vgafb_common_setup: couldn't map mmio");
175:
176: /* memsize should only be visible region for console */
177: memsize = cons_height * cons_linebytes;
178: if (bus_space_map(vc->vc_memt, membase, memsize,
179: /* XXX */ppc_proc_is_64b ? 0 : 1, &vc->vc_memh))
180: panic("vgafb_common_setup: couldn't map memory");
181: cons_display_mem_h = vc->vc_memh;
182: vc->vc_ofh = cons_display_ofh;
183:
184:
185: vc->vc_crow = vc->vc_ccol = 0; /* Has to be some onscreen value */
186: vc->vc_so = 0;
187:
188: /* clear screen, frob cursor, etc.? */
189: /*
190: */
191:
192: vc->vc_at = 0x00 | 0xf; /* black bg|white fg */
193: vc->vc_so_at = 0x00 | 0xf | 0x80; /* black bg|white fg|blink */
194:
195: if (cons_depth == 8) {
196: vgafb_restore_default_colors(vc);
197: }
198: }
199:
200: void
201: vgafb_restore_default_colors(struct vgafb_config *vc)
202: {
203: int i;
204:
205: for (i = 0; i < 256; i++) {
206: const u_char *color;
207:
208: color = &rasops_cmap[i * 3];
209: vgafb_setcolor(vc, i, color[0], color[1], color[2]);
210: }
211: }
212:
213: void
214: vgafb_wsdisplay_attach(struct device *parent, struct vgafb_config *vc,
215: int console)
216: {
217: struct wsemuldisplaydev_attach_args aa;
218:
219: aa.console = console;
220: aa.scrdata = &vgafb_screenlist;
221: aa.accessops = &vgafb_accessops;
222: aa.accesscookie = vc;
223: aa.defaultscreens = 0;
224:
225: /* no need to keep the burner function if no hw support */
226: if (cons_backlight_available == 0)
227: vgafb_accessops.burn_screen = NULL;
228: else {
229: vc->vc_backlight_on = WSDISPLAYIO_VIDEO_OFF;
230: vgafb_burn(vc, WSDISPLAYIO_VIDEO_ON, 0); /* paranoia */
231: }
232:
233: config_found(parent, &aa, wsemuldisplaydevprint);
234: }
235:
236: int
237: vgafb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
238: {
239: struct vgafb_config *vc = v;
240: struct wsdisplay_fbinfo *wdf;
241:
242: switch (cmd) {
243: case WSDISPLAYIO_GTYPE:
244: *(u_int *)data = WSDISPLAY_TYPE_PCIVGA;
245: return 0;
246: case WSDISPLAYIO_GINFO:
247: wdf = (void *)data;
248: wdf->height = cons_height;
249: wdf->width = cons_width;
250: wdf->depth = cons_depth;
251: wdf->cmsize = 256;
252: return 0;
253:
254: case WSDISPLAYIO_LINEBYTES:
255: *(u_int *)data = cons_linebytes;
256: return 0;
257:
258: case WSDISPLAYIO_GETCMAP:
259: return vgafb_getcmap(vc, (struct wsdisplay_cmap *)data);
260:
261: case WSDISPLAYIO_PUTCMAP:
262: return vgafb_putcmap(vc, (struct wsdisplay_cmap *)data);
263:
264: case WSDISPLAYIO_SMODE:
265: vc->vc_mode = *(u_int *)data;
266: /* track the state of the display,
267: * if returning to WSDISPLAYIO_MODE_EMUL
268: * restore the last palette, workaround for
269: * bad accellerated X servers that does not restore
270: * the correct palette.
271: */
272: if (cons_depth == 8)
273: vgafb_restore_default_colors(vc);
274: break;
275:
276: case WSDISPLAYIO_GETPARAM:
277: {
278: struct wsdisplay_param *dp = (struct wsdisplay_param *)data;
279:
280: switch (dp->param) {
281: case WSDISPLAYIO_PARAM_BRIGHTNESS:
282: if (cons_backlight_available != 0) {
283: dp->min = MIN_BRIGHTNESS;
284: dp->max = MAX_BRIGHTNESS;
285: dp->curval = cons_brightness;
286: return 0;
287: }
288: return -1;
289: case WSDISPLAYIO_PARAM_BACKLIGHT:
290: if (cons_backlight_available != 0) {
291: dp->min = 0;
292: dp->max = 1;
293: dp->curval = vc->vc_backlight_on;
294: return 0;
295: } else
296: return -1;
297: }
298: }
299: return -1;
300:
301: case WSDISPLAYIO_SETPARAM:
302: {
303: struct wsdisplay_param *dp = (struct wsdisplay_param *)data;
304:
305: switch (dp->param) {
306: case WSDISPLAYIO_PARAM_BRIGHTNESS:
307: if (cons_backlight_available == 1) {
308: of_setbrightness(dp->curval);
309: return 0;
310: } else
311: return -1;
312: case WSDISPLAYIO_PARAM_BACKLIGHT:
313: if (cons_backlight_available != 0) {
314: vgafb_burn(vc,
315: dp->curval ? WSDISPLAYIO_VIDEO_ON :
316: WSDISPLAYIO_VIDEO_OFF, 0);
317: return 0;
318: } else
319: return -1;
320: }
321: }
322: return -1;
323:
324: case WSDISPLAYIO_SVIDEO:
325: case WSDISPLAYIO_GVIDEO:
326: break;
327:
328: case WSDISPLAYIO_GCURPOS:
329: case WSDISPLAYIO_SCURPOS:
330: case WSDISPLAYIO_GCURMAX:
331: case WSDISPLAYIO_GCURSOR:
332: case WSDISPLAYIO_SCURSOR:
333: default:
334: return -1; /* not supported yet */
335: }
336:
337: return (0);
338: }
339:
340: paddr_t
341: vgafb_mmap(void *v, off_t offset, int prot)
342: {
343: struct vgafb_config *vc = v;
344: bus_space_handle_t h;
345:
346: switch (vc->vc_mode) {
347: case WSDISPLAYIO_MODE_MAPPED:
348: #ifdef APERTURE
349: if (allowaperture == 0) {
350: h = -1;
351: break;
352: }
353: #endif
354: if (offset >= 0xa0000 && offset < 0xfffff)
355: h = offset;
356: /* XXX the following are probably wrong.
357: we want physical addresses here, not virtual ones */
358: else if (offset >= 0x10000000 && offset < 0x10040000 )
359: /* 256KB of iohb */
360: h = vc->vc_ioh_b;
361: else if (offset >= 0x10040000 && offset < 0x10080000)
362: /* 256KB of iohc */
363: h = vc->vc_ioh_c;
364: else if (offset >= 0x18880000 && offset < 0x100c0000)
365: /* 256KB of iohd */
366: h = vc->vc_ioh_d;
367: else if (offset >= 0x20000000 && offset < 0x20000000+vc->mmiosize)
368: /* mmiosize... */
369: h = vc->vc_mmioh + (offset - 0x20000000);
370: else if (offset >= vc->membase && (offset < vc->membase+vc->memsize)) {
371: /* allow mmapping of memory */
372: h = offset;
373: } else if (offset >= vc->mmiobase &&
374: (offset < vc->mmiobase+vc->mmiosize)) {
375: /* allow mmapping of mmio space */
376: h = offset;
377:
378: } else {
379: h = -1;
380: }
381: break;
382:
383: case WSDISPLAYIO_MODE_DUMBFB:
384: if (offset >= 0x00000 && offset < vc->memsize)
385: h = vc->vc_paddr + offset;
386: break;
387:
388: }
389: return h;
390: }
391:
392:
393: void
394: vgafb_cnprobe(struct consdev *cp)
395: {
396: if (cons_displaytype != 1)
397: return;
398:
399: cp->cn_pri = CN_INTERNAL;
400: }
401:
402: void
403: vgafb_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, void *pc, int bus,
404: int device, int function)
405: {
406: long defattr;
407:
408: struct vgafb_devconfig *dc = &vgafb_console_dc;
409: struct rasops_info *ri = &dc->dc_rinfo;
410:
411: ri->ri_flg = RI_CENTER;
412: ri->ri_depth = cons_depth;
413: ri->ri_bits = (void *)cons_display_mem_h;
414: ri->ri_width = cons_width;
415: ri->ri_height = cons_height;
416: ri->ri_stride = cons_linebytes;
417: ri->ri_hw = dc;
418:
419: rasops_init(ri, 160, 160); /* XXX */
420:
421: vgafb_stdscreen.nrows = ri->ri_rows;
422: vgafb_stdscreen.ncols = ri->ri_cols;
423: vgafb_stdscreen.textops = &ri->ri_ops;
424: ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
425:
426: wsdisplay_cnattach(&vgafb_stdscreen, ri, 0, 0, defattr);
427: }
428:
429: struct {
430: u_int8_t r;
431: u_int8_t g;
432: u_int8_t b;
433: } vgafb_color[256];
434:
435: void
436: vgafb_setcolor(struct vgafb_config *vc, unsigned int index, u_int8_t r,
437: u_int8_t g, u_int8_t b)
438: {
439: vc->vc_cmap_red[index] = r;
440: vc->vc_cmap_green[index] = g;
441: vc->vc_cmap_blue[index] = b;
442:
443: vgafb_color[index].r = r;
444: vgafb_color[index].g = g;
445: vgafb_color[index].b = b;
446: OF_call_method_1("set-colors", cons_display_ofh, 3,
447: &vgafb_color[index], index, 1);
448: }
449:
450: int
451: vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm)
452: {
453: u_int index = cm->index;
454: u_int count = cm->count;
455: int error;
456:
457: if (index >= 256 || count > 256 - index)
458: return EINVAL;
459:
460: error = copyout(&vc->vc_cmap_red[index], cm->red, count);
461: if (error)
462: return error;
463: error = copyout(&vc->vc_cmap_green[index], cm->green, count);
464: if (error)
465: return error;
466: error = copyout(&vc->vc_cmap_blue[index], cm->blue, count);
467: if (error)
468: return error;
469:
470: return 0;
471: }
472:
473: int
474: vgafb_putcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm)
475: {
476: u_int index = cm->index;
477: u_int count = cm->count;
478: u_int i;
479: int error;
480: u_int8_t *r, *g, *b;
481:
482: if (index >= 256 || count > 256 - index)
483: return EINVAL;
484:
485: if ((error = copyin(cm->red, &vc->vc_cmap_red[index], count)) != 0)
486: return (error);
487: if ((error = copyin(cm->green, &vc->vc_cmap_green[index], count)) != 0)
488: return (error);
489: if ((error = copyin(cm->blue, &vc->vc_cmap_blue[index], count)) != 0)
490: return (error);
491:
492: r = &(vc->vc_cmap_red[index]);
493: g = &(vc->vc_cmap_green[index]);
494: b = &(vc->vc_cmap_blue[index]);
495:
496: for (i = 0; i < count; i++) {
497: vgafb_color[i].r = *r;
498: vgafb_color[i].g = *g;
499: vgafb_color[i].b = *b;
500: r++, g++, b++;
501: }
502: OF_call_method_1("set-colors", cons_display_ofh, 3,
503: &vgafb_color, index, count);
504: return 0;
505: }
506:
507: void
508: vgafb_burn(void *v, u_int on, u_int flags)
509: {
510: struct vgafb_config *vc = v;
511:
512: if (cons_backlight_available == 1 &&
513: vc->vc_backlight_on != on) {
514: if (on == WSDISPLAYIO_VIDEO_ON) {
515: OF_call_method_1("backlight-on", cons_display_ofh, 0);
516: } else {
517: OF_call_method_1("backlight-off", cons_display_ofh, 0);
518: }
519: vc->vc_backlight_on = on;
520: }
521: }
CVSweb