| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: p9100.c,v 1.44 2009/05/27 00:35:34 macallan Exp $ */ | | 1 | /* $NetBSD: p9100.c,v 1.45 2009/05/27 15:13:22 macallan Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2005, 2006 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998, 2005, 2006 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Matt Thomas. | | 8 | * by Matt Thomas. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -28,27 +28,27 @@ | | | @@ -28,27 +28,27 @@ |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * color display (p9100) driver. | | 33 | * color display (p9100) driver. |
34 | * | | 34 | * |
35 | * Does not handle interrupts, even though they can occur. | | 35 | * Does not handle interrupts, even though they can occur. |
36 | * | | 36 | * |
37 | * XXX should defer colormap updates to vertical retrace interrupts | | 37 | * XXX should defer colormap updates to vertical retrace interrupts |
38 | */ | | 38 | */ |
39 | | | 39 | |
40 | #include <sys/cdefs.h> | | 40 | #include <sys/cdefs.h> |
41 | __KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1.44 2009/05/27 00:35:34 macallan Exp $"); | | 41 | __KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1.45 2009/05/27 15:13:22 macallan Exp $"); |
42 | | | 42 | |
43 | #include <sys/param.h> | | 43 | #include <sys/param.h> |
44 | #include <sys/systm.h> | | 44 | #include <sys/systm.h> |
45 | #include <sys/buf.h> | | 45 | #include <sys/buf.h> |
46 | #include <sys/device.h> | | 46 | #include <sys/device.h> |
47 | #include <sys/ioctl.h> | | 47 | #include <sys/ioctl.h> |
48 | #include <sys/malloc.h> | | 48 | #include <sys/malloc.h> |
49 | #include <sys/mman.h> | | 49 | #include <sys/mman.h> |
50 | #include <sys/tty.h> | | 50 | #include <sys/tty.h> |
51 | #include <sys/conf.h> | | 51 | #include <sys/conf.h> |
52 | | | 52 | |
53 | #include <sys/bus.h> | | 53 | #include <sys/bus.h> |
54 | #include <machine/autoconf.h> | | 54 | #include <machine/autoconf.h> |
| @@ -61,31 +61,32 @@ __KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1. | | | @@ -61,31 +61,32 @@ __KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1. |
61 | #include <dev/sbus/p9100reg.h> | | 61 | #include <dev/sbus/p9100reg.h> |
62 | | | 62 | |
63 | #include <dev/sbus/sbusvar.h> | | 63 | #include <dev/sbus/sbusvar.h> |
64 | | | 64 | |
65 | #include <dev/wscons/wsdisplayvar.h> | | 65 | #include <dev/wscons/wsdisplayvar.h> |
66 | #include <dev/wscons/wsconsio.h> | | 66 | #include <dev/wscons/wsconsio.h> |
67 | #include <dev/wsfont/wsfont.h> | | 67 | #include <dev/wsfont/wsfont.h> |
68 | #include <dev/rasops/rasops.h> | | 68 | #include <dev/rasops/rasops.h> |
69 | | | 69 | |
70 | #include <dev/wscons/wsdisplay_vconsvar.h> | | 70 | #include <dev/wscons/wsdisplay_vconsvar.h> |
71 | | | 71 | |
72 | #include "opt_wsemul.h" | | 72 | #include "opt_wsemul.h" |
73 | #include "rasops_glue.h" | | 73 | #include "rasops_glue.h" |
| | | 74 | #include "opt_pnozz.h" |
74 | | | 75 | |
75 | #include "tctrl.h" | | 76 | #include "tctrl.h" |
76 | #if NTCTRL > 0 | | 77 | #if NTCTRL > 0 |
77 | #include <machine/tctrl.h> | | 78 | #include <machine/tctrl.h> |
78 | #include <sparc/dev/tctrlvar.h>/*XXX*/ | | 79 | #include <sparc/dev/tctrlvar.h> /*XXX*/ |
79 | #endif | | 80 | #endif |
80 | | | 81 | |
81 | #ifdef PNOZZ_DEBUG | | 82 | #ifdef PNOZZ_DEBUG |
82 | #define DPRINTF aprint_normal | | 83 | #define DPRINTF aprint_normal |
83 | #else | | 84 | #else |
84 | #define DPRINTF while (0) aprint_normal | | 85 | #define DPRINTF while (0) aprint_normal |
85 | #endif | | 86 | #endif |
86 | | | 87 | |
87 | struct pnozz_cursor { | | 88 | struct pnozz_cursor { |
88 | short pc_enable; /* cursor is enabled */ | | 89 | short pc_enable; /* cursor is enabled */ |
89 | struct fbcurpos pc_pos; /* position */ | | 90 | struct fbcurpos pc_pos; /* position */ |
90 | struct fbcurpos pc_hot; /* hot-spot */ | | 91 | struct fbcurpos pc_hot; /* hot-spot */ |
91 | struct fbcurpos pc_size; /* size of mask & image fields */ | | 92 | struct fbcurpos pc_size; /* size of mask & image fields */ |
| @@ -96,83 +97,79 @@ struct pnozz_cursor { | | | @@ -96,83 +97,79 @@ struct pnozz_cursor { |
96 | | | 97 | |
97 | /* per-display variables */ | | 98 | /* per-display variables */ |
98 | struct p9100_softc { | | 99 | struct p9100_softc { |
99 | device_t sc_dev; /* base device */ | | 100 | device_t sc_dev; /* base device */ |
100 | struct sbusdev sc_sd; /* sbus device */ | | 101 | struct sbusdev sc_sd; /* sbus device */ |
101 | struct fbdevice sc_fb; /* frame buffer device */ | | 102 | struct fbdevice sc_fb; /* frame buffer device */ |
102 | | | 103 | |
103 | bus_space_tag_t sc_bustag; | | 104 | bus_space_tag_t sc_bustag; |
104 | | | 105 | |
105 | bus_addr_t sc_ctl_paddr; /* phys address description */ | | 106 | bus_addr_t sc_ctl_paddr; /* phys address description */ |
106 | bus_size_t sc_ctl_psize; /* for device mmap() */ | | 107 | bus_size_t sc_ctl_psize; /* for device mmap() */ |
107 | bus_space_handle_t sc_ctl_memh; /* bus space handle */ | | 108 | bus_space_handle_t sc_ctl_memh; /* bus space handle */ |
108 | | | 109 | |
109 | #if 0 | | | |
110 | bus_addr_t sc_cmd_paddr; /* phys address description */ | | | |
111 | bus_size_t sc_cmd_psize; /* for device mmap() */ | | | |
112 | bus_space_handle_t sc_cmd_memh; /* bus space handle */ | | | |
113 | #endif | | | |
114 | bus_addr_t sc_fb_paddr; /* phys address description */ | | 110 | bus_addr_t sc_fb_paddr; /* phys address description */ |
115 | bus_size_t sc_fb_psize; /* for device mmap() */ | | 111 | bus_size_t sc_fb_psize; /* for device mmap() */ |
116 | bus_space_handle_t sc_fb_memh; /* bus space handle */ | | 112 | bus_space_handle_t sc_fb_memh; /* bus space handle */ |
117 | | | 113 | |
118 | volatile uint32_t sc_junk; | | 114 | volatile uint32_t sc_junk; |
119 | uint32_t sc_mono_width; /* for setup_mono */ | | 115 | uint32_t sc_mono_width; /* for setup_mono */ |
120 | | | 116 | |
121 | uint32_t sc_width; | | 117 | uint32_t sc_width; |
122 | uint32_t sc_height; /* panel width / height */ | | 118 | uint32_t sc_height; /* panel width / height */ |
123 | uint32_t sc_stride; | | 119 | uint32_t sc_stride; |
124 | uint32_t sc_depth; | | 120 | uint32_t sc_depth; |
125 | int sc_depthshift; /* blitter works on bytes not pixels */ | | 121 | int sc_depthshift; /* blitter works on bytes not pixels */ |
126 | | | 122 | |
127 | union bt_cmap sc_cmap; /* Brooktree color map */ | | 123 | union bt_cmap sc_cmap; /* Brooktree color map */ |
128 | | | 124 | |
129 | struct pnozz_cursor sc_cursor; | | 125 | struct pnozz_cursor sc_cursor; |
130 | | | 126 | |
131 | int sc_mode; | | 127 | int sc_mode; |
132 | int sc_video, sc_powerstate; | | 128 | int sc_video, sc_powerstate; |
133 | uint32_t sc_bg; | | 129 | uint32_t sc_bg; |
134 | volatile uint32_t sc_last_offset; | | 130 | volatile uint32_t sc_last_offset; |
135 | struct vcons_data vd; | | 131 | struct vcons_data vd; |
| | | 132 | uint8_t sc_dac_power; |
136 | }; | | 133 | }; |
137 | | | 134 | |
138 | | | 135 | |
139 | static struct vcons_screen p9100_console_screen; | | 136 | static struct vcons_screen p9100_console_screen; |
140 | | | 137 | |
141 | extern const u_char rasops_cmap[768]; | | 138 | extern const u_char rasops_cmap[768]; |
142 | | | 139 | |
143 | struct wsscreen_descr p9100_defscreendesc = { | | 140 | struct wsscreen_descr p9100_defscreendesc = { |
144 | "default", | | 141 | "default", |
145 | 0, 0, | | 142 | 0, 0, |
146 | NULL, | | 143 | NULL, |
147 | 8, 16, | | 144 | 8, 16, |
148 | WSSCREEN_WSCOLORS, | | 145 | WSSCREEN_WSCOLORS, |
149 | }; | | 146 | }; |
150 | | | 147 | |
151 | const struct wsscreen_descr *_p9100_scrlist[] = { | | 148 | const struct wsscreen_descr *_p9100_scrlist[] = { |
152 | &p9100_defscreendesc, | | 149 | &p9100_defscreendesc, |
153 | /* XXX other formats, graphics screen? */ | | 150 | /* XXX other formats, graphics screen? */ |
154 | }; | | 151 | }; |
155 | | | 152 | |
156 | struct wsscreen_list p9100_screenlist = { | | 153 | struct wsscreen_list p9100_screenlist = { |
157 | sizeof(_p9100_scrlist) / sizeof(struct wsscreen_descr *), _p9100_scrlist | | 154 | sizeof(_p9100_scrlist) / sizeof(struct wsscreen_descr *), |
| | | 155 | _p9100_scrlist |
158 | }; | | 156 | }; |
159 | | | 157 | |
160 | /* autoconfiguration driver */ | | 158 | /* autoconfiguration driver */ |
161 | static int p9100_sbus_match(device_t, cfdata_t, void *); | | 159 | static int p9100_sbus_match(device_t, cfdata_t, void *); |
162 | static void p9100_sbus_attach(device_t, device_t, void *); | | 160 | static void p9100_sbus_attach(device_t, device_t, void *); |
163 | | | 161 | |
164 | static void p9100unblank(device_t); | | 162 | static void p9100unblank(device_t); |
165 | static void p9100_shutdown(void *); | | | |
166 | | | 163 | |
167 | CFATTACH_DECL_NEW(pnozz, sizeof(struct p9100_softc), | | 164 | CFATTACH_DECL_NEW(pnozz, sizeof(struct p9100_softc), |
168 | p9100_sbus_match, p9100_sbus_attach, NULL, NULL); | | 165 | p9100_sbus_match, p9100_sbus_attach, NULL, NULL); |
169 | | | 166 | |
170 | extern struct cfdriver pnozz_cd; | | 167 | extern struct cfdriver pnozz_cd; |
171 | | | 168 | |
172 | static dev_type_open(p9100open); | | 169 | static dev_type_open(p9100open); |
173 | static dev_type_ioctl(p9100ioctl); | | 170 | static dev_type_ioctl(p9100ioctl); |
174 | static dev_type_mmap(p9100mmap); | | 171 | static dev_type_mmap(p9100mmap); |
175 | | | 172 | |
176 | const struct cdevsw pnozz_cdevsw = { | | 173 | const struct cdevsw pnozz_cdevsw = { |
177 | p9100open, nullclose, noread, nowrite, p9100ioctl, | | 174 | p9100open, nullclose, noread, nowrite, p9100ioctl, |
178 | nostop, notty, nopoll, p9100mmap, nokqfilter, | | 175 | nostop, notty, nopoll, p9100mmap, nokqfilter, |
| @@ -210,51 +207,50 @@ static void p9100_setup_mono(struct p910 | | | @@ -210,51 +207,50 @@ static void p9100_setup_mono(struct p910 |
210 | uint32_t, uint32_t); | | 207 | uint32_t, uint32_t); |
211 | static void p9100_feed_line(struct p9100_softc *, int, uint8_t *); | | 208 | static void p9100_feed_line(struct p9100_softc *, int, uint8_t *); |
212 | static void p9100_set_color_reg(struct p9100_softc *, int, int32_t); | | 209 | static void p9100_set_color_reg(struct p9100_softc *, int, int32_t); |
213 | | | 210 | |
214 | static void p9100_copycols(void *, int, int, int, int); | | 211 | static void p9100_copycols(void *, int, int, int, int); |
215 | static void p9100_erasecols(void *, int, int, int, long); | | 212 | static void p9100_erasecols(void *, int, int, int, long); |
216 | static void p9100_copyrows(void *, int, int, int); | | 213 | static void p9100_copyrows(void *, int, int, int); |
217 | static void p9100_eraserows(void *, int, int, long); | | 214 | static void p9100_eraserows(void *, int, int, long); |
218 | /*static int p9100_mapchar(void *, int, u_int *);*/ | | 215 | /*static int p9100_mapchar(void *, int, u_int *);*/ |
219 | static void p9100_putchar(void *, int, int, u_int, long); | | 216 | static void p9100_putchar(void *, int, int, u_int, long); |
220 | static void p9100_cursor(void *, int, int, int); | | 217 | static void p9100_cursor(void *, int, int, int); |
221 | static int p9100_allocattr(void *, int, int, int, long *); | | 218 | static int p9100_allocattr(void *, int, int, int, long *); |
222 | | | 219 | |
223 | /*static void p9100_scroll(void *, void *, int);*/ | | | |
224 | | | | |
225 | static int p9100_putcmap(struct p9100_softc *, struct wsdisplay_cmap *); | | 220 | static int p9100_putcmap(struct p9100_softc *, struct wsdisplay_cmap *); |
226 | static int p9100_getcmap(struct p9100_softc *, struct wsdisplay_cmap *); | | 221 | static int p9100_getcmap(struct p9100_softc *, struct wsdisplay_cmap *); |
227 | static int p9100_ioctl(void *, void *, u_long, void *, int, struct lwp *); | | 222 | static int p9100_ioctl(void *, void *, u_long, void *, int, struct lwp *); |
228 | static paddr_t p9100_mmap(void *, void *, off_t, int); | | 223 | static paddr_t p9100_mmap(void *, void *, off_t, int); |
229 | | | 224 | |
230 | /*static int p9100_load_font(void *, void *, struct wsdisplay_font *);*/ | | 225 | /*static int p9100_load_font(void *, void *, struct wsdisplay_font *);*/ |
231 | | | 226 | |
232 | static void p9100_init_screen(void *, struct vcons_screen *, int, | | 227 | static void p9100_init_screen(void *, struct vcons_screen *, int, |
233 | long *); | | 228 | long *); |
234 | #endif | | 229 | #endif |
235 | | | 230 | |
236 | static void p9100_init_cursor(struct p9100_softc *); | | 231 | static void p9100_init_cursor(struct p9100_softc *); |
237 | | | 232 | |
238 | static void p9100_set_fbcursor(struct p9100_softc *); | | 233 | static void p9100_set_fbcursor(struct p9100_softc *); |
239 | static void p9100_setcursorcmap(struct p9100_softc *); | | 234 | static void p9100_setcursorcmap(struct p9100_softc *); |
240 | static void p9100_loadcursor(struct p9100_softc *); | | 235 | static void p9100_loadcursor(struct p9100_softc *); |
241 | | | 236 | |
242 | #if 0 | | 237 | #if 0 |
243 | static int p9100_intr(void *); | | 238 | static int p9100_intr(void *); |
244 | #endif | | 239 | #endif |
245 | | | 240 | |
246 | /* power management stuff */ | | 241 | /* power management stuff */ |
247 | static void p9100_power_hook(int, void *); | | 242 | static bool p9100_suspend(device_t PMF_FN_PROTO); |
| | | 243 | static bool p9100_resume(device_t PMF_FN_PROTO); |
248 | | | 244 | |
249 | #if NTCTRL > 0 | | 245 | #if NTCTRL > 0 |
250 | static void p9100_set_extvga(void *, int); | | 246 | static void p9100_set_extvga(void *, int); |
251 | #endif | | 247 | #endif |
252 | | | 248 | |
253 | #if NWSDISPLAY > 0 | | 249 | #if NWSDISPLAY > 0 |
254 | struct wsdisplay_accessops p9100_accessops = { | | 250 | struct wsdisplay_accessops p9100_accessops = { |
255 | p9100_ioctl, | | 251 | p9100_ioctl, |
256 | p9100_mmap, | | 252 | p9100_mmap, |
257 | NULL, /* vcons_alloc_screen */ | | 253 | NULL, /* vcons_alloc_screen */ |
258 | NULL, /* vcons_free_screen */ | | 254 | NULL, /* vcons_free_screen */ |
259 | NULL, /* vcons_show_screen */ | | 255 | NULL, /* vcons_show_screen */ |
260 | NULL, /* load_font */ | | 256 | NULL, /* load_font */ |
| @@ -298,28 +294,27 @@ p9100_sbus_attach(device_t parent, devic | | | @@ -298,28 +294,27 @@ p9100_sbus_attach(device_t parent, devic |
298 | | | 294 | |
299 | #if NWSDISPLAY > 0 | | 295 | #if NWSDISPLAY > 0 |
300 | struct wsemuldisplaydev_attach_args aa; | | 296 | struct wsemuldisplaydev_attach_args aa; |
301 | struct rasops_info *ri; | | 297 | struct rasops_info *ri; |
302 | unsigned long defattr; | | 298 | unsigned long defattr; |
303 | #endif | | 299 | #endif |
304 | | | 300 | |
305 | sc->sc_last_offset = 0xffffffff; | | 301 | sc->sc_last_offset = 0xffffffff; |
306 | sc->sc_dev = self; | | 302 | sc->sc_dev = self; |
307 | | | 303 | |
308 | /* | | 304 | /* |
309 | * When the ROM has mapped in a p9100 display, the address | | 305 | * When the ROM has mapped in a p9100 display, the address |
310 | * maps only the video RAM, so in any case we have to map the | | 306 | * maps only the video RAM, so in any case we have to map the |
311 | * registers ourselves. We only need the video RAM if we are | | 307 | * registers ourselves. |
312 | * going to print characters via rconsole. | | | |
313 | */ | | 308 | */ |
314 | | | 309 | |
315 | if (sa->sa_npromvaddrs != 0) | | 310 | if (sa->sa_npromvaddrs != 0) |
316 | fb->fb_pixels = (void *)sa->sa_promvaddrs[0]; | | 311 | fb->fb_pixels = (void *)sa->sa_promvaddrs[0]; |
317 | | | 312 | |
318 | /* Remember cookies for p9100_mmap() */ | | 313 | /* Remember cookies for p9100_mmap() */ |
319 | sc->sc_bustag = sa->sa_bustag; | | 314 | sc->sc_bustag = sa->sa_bustag; |
320 | | | 315 | |
321 | sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag, | | 316 | sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag, |
322 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base); | | 317 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base); |
323 | sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/ | | 318 | sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/ |
324 | | | 319 | |
325 | sc->sc_fb_paddr = sbus_bus_addr(sa->sa_bustag, | | 320 | sc->sc_fb_paddr = sbus_bus_addr(sa->sa_bustag, |
| @@ -330,32 +325,40 @@ p9100_sbus_attach(device_t parent, devic | | | @@ -330,32 +325,40 @@ p9100_sbus_attach(device_t parent, devic |
330 | sa->sa_reg[0].oa_space, | | 325 | sa->sa_reg[0].oa_space, |
331 | sa->sa_reg[0].oa_base, | | 326 | sa->sa_reg[0].oa_base, |
332 | /* | | 327 | /* |
333 | * XXX for some reason the SBus resources don't cover | | 328 | * XXX for some reason the SBus resources don't cover |
334 | * all registers, so we just map what we need | | 329 | * all registers, so we just map what we need |
335 | */ | | 330 | */ |
336 | 0x8000, | | 331 | 0x8000, |
337 | 0, &sc->sc_ctl_memh) != 0) { | | 332 | 0, &sc->sc_ctl_memh) != 0) { |
338 | printf("%s: cannot map control registers\n", | | 333 | printf("%s: cannot map control registers\n", |
339 | self->dv_xname); | | 334 | self->dv_xname); |
340 | return; | | 335 | return; |
341 | } | | 336 | } |
342 | | | 337 | |
| | | 338 | /* |
| | | 339 | * we need to map the framebuffer even though we never write to it, |
| | | 340 | * thanks to some weirdness in the SPARCbook's SBus glue for the |
| | | 341 | * P9100 - all register accesses need to be 'latched in' whenever we |
| | | 342 | * go to another 0x80 aligned 'page' by reading the framebuffer at the |
| | | 343 | * same offset |
| | | 344 | */ |
343 | if (fb->fb_pixels == NULL) { | | 345 | if (fb->fb_pixels == NULL) { |
344 | if (sbus_bus_map(sc->sc_bustag, | | 346 | if (sbus_bus_map(sc->sc_bustag, |
345 | sa->sa_reg[2].oa_space, | | 347 | sa->sa_reg[2].oa_space, |
346 | sa->sa_reg[2].oa_base, | | 348 | sa->sa_reg[2].oa_base, |
347 | sc->sc_fb_psize, | | 349 | sc->sc_fb_psize, |
348 | BUS_SPACE_MAP_LINEAR, &sc->sc_fb_memh) != 0) { | | 350 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, |
| | | 351 | &sc->sc_fb_memh) != 0) { |
349 | printf("%s: cannot map framebuffer\n", | | 352 | printf("%s: cannot map framebuffer\n", |
350 | self->dv_xname); | | 353 | self->dv_xname); |
351 | return; | | 354 | return; |
352 | } | | 355 | } |
353 | fb->fb_pixels = (char *)sc->sc_fb_memh; | | 356 | fb->fb_pixels = (char *)sc->sc_fb_memh; |
354 | } else { | | 357 | } else { |
355 | sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels; | | 358 | sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels; |
356 | } | | 359 | } |
357 | sc->sc_width = prom_getpropint(node, "width", 800); | | 360 | sc->sc_width = prom_getpropint(node, "width", 800); |
358 | sc->sc_height = prom_getpropint(node, "height", 600); | | 361 | sc->sc_height = prom_getpropint(node, "height", 600); |
359 | sc->sc_depth = prom_getpropint(node, "depth", 8) >> 3; | | 362 | sc->sc_depth = prom_getpropint(node, "depth", 8) >> 3; |
360 | | | 363 | |
361 | sc->sc_stride = prom_getpropint(node, "linebytes", | | 364 | sc->sc_stride = prom_getpropint(node, "linebytes", |
| @@ -372,97 +375,29 @@ p9100_sbus_attach(device_t parent, devic | | | @@ -372,97 +375,29 @@ p9100_sbus_attach(device_t parent, devic |
372 | fb->fb_pixels = NULL; | | 375 | fb->fb_pixels = NULL; |
373 | | | 376 | |
374 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | | 377 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; |
375 | | | 378 | |
376 | isconsole = fb_is_console(node); | | 379 | isconsole = fb_is_console(node); |
377 | #if 0 | | 380 | #if 0 |
378 | if (!isconsole) { | | 381 | if (!isconsole) { |
379 | aprint_normal("\n"); | | 382 | aprint_normal("\n"); |
380 | aprint_error_dev(self, "fatal error: PROM didn't configure device\n"); | | 383 | aprint_error_dev(self, "fatal error: PROM didn't configure device\n"); |
381 | return; | | 384 | return; |
382 | } | | 385 | } |
383 | #endif | | 386 | #endif |
384 | | | 387 | |
385 | /* | | | |
386 | * When the ROM has mapped in a p9100 display, the address | | | |
387 | * maps only the video RAM, so in any case we have to map the | | | |
388 | * registers ourselves. We only need the video RAM if we are | | | |
389 | * going to print characters via rconsole. | | | |
390 | */ | | | |
391 | if (sbus_bus_map(sc->sc_bustag, | | | |
392 | sa->sa_reg[0].oa_space, | | | |
393 | sa->sa_reg[0].oa_base, | | | |
394 | /* | | | |
395 | * XXX for some reason the SBus resources don't cover | | | |
396 | * all registers, so we just map what we need | | | |
397 | */ | | | |
398 | /*sc->sc_ctl_psize*/ 0x8000, | | | |
399 | /*BUS_SPACE_MAP_LINEAR*/0, &sc->sc_ctl_memh) != 0) { | | | |
400 | aprint_error_dev(self, "cannot map control registers\n"); | | | |
401 | return; | | | |
402 | } | | | |
403 | | | | |
404 | if (sa->sa_npromvaddrs != 0) | | | |
405 | fb->fb_pixels = (void *)sa->sa_promvaddrs[0]; | | | |
406 | | | | |
407 | if (fb->fb_pixels == NULL) { | | | |
408 | if (sbus_bus_map(sc->sc_bustag, | | | |
409 | sa->sa_reg[2].oa_space, | | | |
410 | sa->sa_reg[2].oa_base, | | | |
411 | sc->sc_fb_psize, | | | |
412 | BUS_SPACE_MAP_LINEAR, &sc->sc_fb_memh) != 0) { | | | |
413 | aprint_error_dev(self, "cannot map framebuffer\n"); | | | |
414 | return; | | | |
415 | } | | | |
416 | fb->fb_pixels = (char *)sc->sc_fb_memh; | | | |
417 | } else { | | | |
418 | sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels; | | | |
419 | } | | | |
420 | | | | |
421 | #if 0 | | | |
422 | /* | | | |
423 | * we set our own depth and OBP won't hand us anything else than 8 bit | | | |
424 | * anyway | | | |
425 | */ | | | |
426 | i = p9100_ctl_read_4(sc, 0x0004); | | | |
427 | switch ((i >> 26) & 7) { | | | |
428 | case 5: | | | |
429 | fb->fb_type.fb_depth = 32; | | | |
430 | sc->sc_depth = 4; | | | |
431 | sc->sc_depthshift = 2; | | | |
432 | break; | | | |
433 | case 7: | | | |
434 | fb->fb_type.fb_depth = 24; | | | |
435 | /* bitch and moan */ | | | |
436 | break; | | | |
437 | case 3: | | | |
438 | fb->fb_type.fb_depth = 16; | | | |
439 | sc->sc_depth = 2; | | | |
440 | sc->sc_depthshift = 1; | | | |
441 | break; | | | |
442 | case 2: | | | |
443 | fb->fb_type.fb_depth = 8; | | | |
444 | sc->sc_depth = 1; | | | |
445 | sc->sc_depthshift = 0; | | | |
446 | break; | | | |
447 | default: { | | | |
448 | panic("pnozz: can't determine screen depth (0x%02x)", i); | | | |
449 | } | | | |
450 | } | | | |
451 | #else | | | |
452 | fb->fb_type.fb_depth = 8; | | 388 | fb->fb_type.fb_depth = 8; |
453 | sc->sc_depth = 1; | | 389 | sc->sc_depth = 1; |
454 | sc->sc_depthshift = 0; | | 390 | sc->sc_depthshift = 0; |
455 | #endif | | | |
456 | | | 391 | |
457 | /* check the RAMDAC */ | | 392 | /* check the RAMDAC */ |
458 | ver = p9100_ramdac_read_ctl(sc, DAC_VERSION); | | 393 | ver = p9100_ramdac_read_ctl(sc, DAC_VERSION); |
459 | | | 394 | |
460 | p9100_init_engine(sc); | | 395 | p9100_init_engine(sc); |
461 | p9100_set_depth(sc, 8); | | 396 | p9100_set_depth(sc, 8); |
462 | | | 397 | |
463 | fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height, | | 398 | fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height, |
464 | node); | | 399 | node); |
465 | | | 400 | |
466 | sbus_establish(&sc->sc_sd, sc->sc_dev); | | 401 | sbus_establish(&sc->sc_sd, sc->sc_dev); |
467 | #if 0 | | 402 | #if 0 |
468 | bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO, | | 403 | bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO, |
| @@ -479,28 +414,31 @@ p9100_sbus_attach(device_t parent, devic | | | @@ -479,28 +414,31 @@ p9100_sbus_attach(device_t parent, devic |
479 | sc->sc_cmap.cm_map[i][0] = rasops_cmap[j]; | | 414 | sc->sc_cmap.cm_map[i][0] = rasops_cmap[j]; |
480 | j++; | | 415 | j++; |
481 | sc->sc_cmap.cm_map[i][1] = rasops_cmap[j]; | | 416 | sc->sc_cmap.cm_map[i][1] = rasops_cmap[j]; |
482 | j++; | | 417 | j++; |
483 | sc->sc_cmap.cm_map[i][2] = rasops_cmap[j]; | | 418 | sc->sc_cmap.cm_map[i][2] = rasops_cmap[j]; |
484 | j++; | | 419 | j++; |
485 | } | | 420 | } |
486 | p9100loadcmap(sc, 0, 256); | | 421 | p9100loadcmap(sc, 0, 256); |
487 | | | 422 | |
488 | /* make sure we are not blanked */ | | 423 | /* make sure we are not blanked */ |
489 | if (isconsole) | | 424 | if (isconsole) |
490 | p9100_set_video(sc, 1); | | 425 | p9100_set_video(sc, 1); |
491 | | | 426 | |
492 | if (shutdownhook_establish(p9100_shutdown, sc) == NULL) { | | 427 | /* register with power management */ |
493 | panic("%s: could not establish shutdown hook", | | 428 | sc->sc_video = 1; |
| | | 429 | sc->sc_powerstate = PWR_RESUME; |
| | | 430 | if (!pmf_device_register(self, p9100_suspend, p9100_resume)) { |
| | | 431 | panic("%s: could not register with PMF", |
494 | device_xname(sc->sc_dev)); | | 432 | device_xname(sc->sc_dev)); |
495 | } | | 433 | } |
496 | | | 434 | |
497 | if (isconsole) { | | 435 | if (isconsole) { |
498 | printf(" (console)\n"); | | 436 | printf(" (console)\n"); |
499 | #ifdef RASTERCONSOLE | | 437 | #ifdef RASTERCONSOLE |
500 | /*p9100loadcmap(sc, 255, 1);*/ | | 438 | /*p9100loadcmap(sc, 255, 1);*/ |
501 | fbrcons_init(fb); | | 439 | fbrcons_init(fb); |
502 | #endif | | 440 | #endif |
503 | } else | | 441 | } else |
504 | printf("\n"); | | 442 | printf("\n"); |
505 | | | 443 | |
506 | #if NWSDISPLAY > 0 | | 444 | #if NWSDISPLAY > 0 |
| @@ -524,67 +462,42 @@ p9100_sbus_attach(device_t parent, devic | | | @@ -524,67 +462,42 @@ p9100_sbus_attach(device_t parent, devic |
524 | | | 462 | |
525 | if(isconsole) { | | 463 | if(isconsole) { |
526 | wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr); | | 464 | wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr); |
527 | } | | 465 | } |
528 | | | 466 | |
529 | aa.console = isconsole; | | 467 | aa.console = isconsole; |
530 | aa.scrdata = &p9100_screenlist; | | 468 | aa.scrdata = &p9100_screenlist; |
531 | aa.accessops = &p9100_accessops; | | 469 | aa.accessops = &p9100_accessops; |
532 | aa.accesscookie = &sc->vd; | | 470 | aa.accesscookie = &sc->vd; |
533 | | | 471 | |
534 | config_found(self, &aa, wsemuldisplaydevprint); | | 472 | config_found(self, &aa, wsemuldisplaydevprint); |
535 | #endif | | 473 | #endif |
536 | fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; | | 474 | fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; |
537 | printf(": rev %d / %x, %dx%d, depth %d mem %x", | | 475 | printf("%s: rev %d / %x, %dx%d, depth %d mem %x\n", |
538 | (i & 7), ver, fb->fb_type.fb_width, fb->fb_type.fb_height, | | 476 | device_xname(self), |
539 | fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize); | | 477 | (i & 7), ver, fb->fb_type.fb_width, fb->fb_type.fb_height, |
| | | 478 | fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize); |
540 | /* cursor sprite handling */ | | 479 | /* cursor sprite handling */ |
541 | p9100_init_cursor(sc); | | 480 | p9100_init_cursor(sc); |
542 | | | 481 | |
543 | /* attach the fb */ | | 482 | /* attach the fb */ |
544 | fb_attach(fb, isconsole); | | 483 | fb_attach(fb, isconsole); |
545 | | | 484 | |
546 | /* register with power management */ | | | |
547 | sc->sc_video = 1; | | | |
548 | sc->sc_powerstate = PWR_RESUME; | | | |
549 | powerhook_establish(device_xname(sc->sc_dev), p9100_power_hook, sc); | | | |
550 | | | | |
551 | #if NTCTRL > 0 | | 485 | #if NTCTRL > 0 |
552 | /* register callback for external monitor status change */ | | 486 | /* register callback for external monitor status change */ |
553 | tadpole_register_callback(p9100_set_extvga, sc); | | 487 | tadpole_register_callback(p9100_set_extvga, sc); |
554 | #endif | | 488 | #endif |
555 | } | | 489 | } |
556 | | | 490 | |
557 | static void | | | |
558 | p9100_shutdown(void *arg) | | | |
559 | { | | | |
560 | struct p9100_softc *sc = arg; | | | |
561 | | | | |
562 | #ifdef RASTERCONSOLE | | | |
563 | sc->sc_cmap.cm_map[0][0] = 0xff; | | | |
564 | sc->sc_cmap.cm_map[0][1] = 0xff; | | | |
565 | sc->sc_cmap.cm_map[0][2] = 0xff; | | | |
566 | sc->sc_cmap.cm_map[1][0] = 0; | | | |
567 | sc->sc_cmap.cm_map[1][1] = 0; | | | |
568 | sc->sc_cmap.cm_map[1][2] = 0x00; | | | |
569 | p9100loadcmap(sc, 0, 2); | | | |
570 | sc->sc_cmap.cm_map[255][0] = 0; | | | |
571 | sc->sc_cmap.cm_map[255][1] = 0; | | | |
572 | sc->sc_cmap.cm_map[255][2] = 0; | | | |
573 | p9100loadcmap(sc, 255, 1); | | | |
574 | #endif | | | |
575 | p9100_set_video(sc, 1); | | | |
576 | } | | | |
577 | | | | |
578 | int | | 491 | int |
579 | p9100open(dev_t dev, int flags, int mode, struct lwp *l) | | 492 | p9100open(dev_t dev, int flags, int mode, struct lwp *l) |
580 | { | | 493 | { |
581 | int unit = minor(dev); | | 494 | int unit = minor(dev); |
582 | | | 495 | |
583 | if (device_lookup(&pnozz_cd, unit) == NULL) | | 496 | if (device_lookup(&pnozz_cd, unit) == NULL) |
584 | return (ENXIO); | | 497 | return (ENXIO); |
585 | return (0); | | 498 | return (0); |
586 | } | | 499 | } |
587 | | | 500 | |
588 | int | | 501 | int |
589 | p9100ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) | | 502 | p9100ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) |
590 | { | | 503 | { |
| @@ -964,27 +877,27 @@ p9100_ramdac_write_ctl(struct p9100_soft | | | @@ -964,27 +877,27 @@ p9100_ramdac_write_ctl(struct p9100_soft |
964 | p9100_ramdac_write(sc, DAC_INDX_HI, (off & 0xff00) >> 8); | | 877 | p9100_ramdac_write(sc, DAC_INDX_HI, (off & 0xff00) >> 8); |
965 | p9100_ramdac_write(sc, DAC_INDX_DATA, val); | | 878 | p9100_ramdac_write(sc, DAC_INDX_DATA, val); |
966 | } | | 879 | } |
967 | #endif /* NTCTRL > 0 */ | | 880 | #endif /* NTCTRL > 0 */ |
968 | | | 881 | |
969 | /* | | 882 | /* |
970 | * Undo the effect of an FBIOSVIDEO that turns the video off. | | 883 | * Undo the effect of an FBIOSVIDEO that turns the video off. |
971 | */ | | 884 | */ |
972 | static void | | 885 | static void |
973 | p9100unblank(device_t dev) | | 886 | p9100unblank(device_t dev) |
974 | { | | 887 | { |
975 | struct p9100_softc *sc = device_private(dev); | | 888 | struct p9100_softc *sc = device_private(dev); |
976 | | | 889 | |
977 | p9100_set_video((struct p9100_softc *)dev, 1); | | 890 | p9100_set_video(sc, 1); |
978 | | | 891 | |
979 | /* | | 892 | /* |
980 | * Check if we're in terminal mode. If not force the console screen | | 893 | * Check if we're in terminal mode. If not force the console screen |
981 | * to front so we can see ddb, panic messages and so on | | 894 | * to front so we can see ddb, panic messages and so on |
982 | */ | | 895 | */ |
983 | if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) { | | 896 | if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) { |
984 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | | 897 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; |
985 | if (sc->vd.active != &p9100_console_screen) { | | 898 | if (sc->vd.active != &p9100_console_screen) { |
986 | SCREEN_INVISIBLE(sc->vd.active); | | 899 | SCREEN_INVISIBLE(sc->vd.active); |
987 | sc->vd.active = &p9100_console_screen; | | 900 | sc->vd.active = &p9100_console_screen; |
988 | SCREEN_VISIBLE(&p9100_console_screen); | | 901 | SCREEN_VISIBLE(&p9100_console_screen); |
989 | } | | 902 | } |
990 | p9100_init_engine(sc); | | 903 | p9100_init_engine(sc); |
| @@ -1006,47 +919,60 @@ p9100_set_video(struct p9100_softc *sc, | | | @@ -1006,47 +919,60 @@ p9100_set_video(struct p9100_softc *sc, |
1006 | #if NTCTRL > 0 | | 919 | #if NTCTRL > 0 |
1007 | /* Turn On/Off the TFT if we know how. | | 920 | /* Turn On/Off the TFT if we know how. |
1008 | */ | | 921 | */ |
1009 | tadpole_set_video(enable); | | 922 | tadpole_set_video(enable); |
1010 | #endif | | 923 | #endif |
1011 | } | | 924 | } |
1012 | | | 925 | |
1013 | static int | | 926 | static int |
1014 | p9100_get_video(struct p9100_softc *sc) | | 927 | p9100_get_video(struct p9100_softc *sc) |
1015 | { | | 928 | { |
1016 | return (p9100_ctl_read_4(sc, SCRN_RPNT_CTL_1) & VIDEO_ENABLED) != 0; | | 929 | return (p9100_ctl_read_4(sc, SCRN_RPNT_CTL_1) & VIDEO_ENABLED) != 0; |
1017 | } | | 930 | } |
1018 | | | 931 | |
1019 | static void | | 932 | static bool |
1020 | p9100_power_hook(int why, void *cookie) | | 933 | p9100_suspend(device_t dev PMF_FN_ARGS) |
1021 | { | | 934 | { |
1022 | struct p9100_softc *sc = cookie; | | 935 | struct p9100_softc *sc = device_private(dev); |
1023 | | | 936 | |
1024 | if (why == sc->sc_powerstate) | | 937 | if (sc->sc_powerstate == PWR_SUSPEND) |
1025 | return; | | 938 | return TRUE; |
1026 | | | 939 | |
1027 | switch(why) | | 940 | sc->sc_video = p9100_get_video(sc); |
1028 | { | | 941 | sc->sc_dac_power = p9100_ramdac_read_ctl(sc, DAC_POWER_MGT); |
1029 | case PWR_SUSPEND: | | 942 | p9100_ramdac_write_ctl(sc, DAC_POWER_MGT, |
1030 | case PWR_STANDBY: | | 943 | DAC_POWER_SCLK_DISABLE | |
1031 | sc->sc_video = p9100_get_video(sc); | | 944 | DAC_POWER_DDOT_DISABLE | |
1032 | p9100_set_video(sc, 0); | | 945 | DAC_POWER_SYNC_DISABLE | |
1033 | sc->sc_powerstate = why; | | 946 | DAC_POWER_ICLK_DISABLE | |
1034 | break; | | 947 | DAC_POWER_IPWR_DISABLE); |
1035 | case PWR_RESUME: | | 948 | p9100_set_video(sc, 0); |
1036 | p9100_set_video(sc, sc->sc_video); | | 949 | sc->sc_powerstate = PWR_SUSPEND; |
1037 | sc->sc_powerstate = why; | | 950 | return TRUE; |
1038 | break; | | 951 | } |
1039 | } | | 952 | |
| | | 953 | static bool |
| | | 954 | p9100_resume(device_t dev PMF_FN_ARGS) |
| | | 955 | { |
| | | 956 | struct p9100_softc *sc = device_private(dev); |
| | | 957 | |
| | | 958 | if (sc->sc_powerstate == PWR_RESUME) |
| | | 959 | return TRUE; |
| | | 960 | |
| | | 961 | p9100_ramdac_write_ctl(sc, DAC_POWER_MGT, sc->sc_dac_power); |
| | | 962 | p9100_set_video(sc, sc->sc_video); |
| | | 963 | |
| | | 964 | sc->sc_powerstate = PWR_RESUME; |
| | | 965 | return TRUE; |
1040 | } | | 966 | } |
1041 | | | 967 | |
1042 | /* | | 968 | /* |
1043 | * Load a subset of the current (new) colormap into the IBM RAMDAC. | | 969 | * Load a subset of the current (new) colormap into the IBM RAMDAC. |
1044 | */ | | 970 | */ |
1045 | static void | | 971 | static void |
1046 | p9100loadcmap(struct p9100_softc *sc, int start, int ncolors) | | 972 | p9100loadcmap(struct p9100_softc *sc, int start, int ncolors) |
1047 | { | | 973 | { |
1048 | int i; | | 974 | int i; |
1049 | sc->sc_last_offset = 0xffffffff; | | 975 | sc->sc_last_offset = 0xffffffff; |
1050 | | | 976 | |
1051 | p9100_ramdac_write(sc, DAC_CMAP_WRIDX, start); | | 977 | p9100_ramdac_write(sc, DAC_CMAP_WRIDX, start); |
1052 | | | 978 | |
| @@ -1097,35 +1023,27 @@ p9100mmap(dev_t dev, off_t off, int prot | | | @@ -1097,35 +1023,27 @@ p9100mmap(dev_t dev, off_t off, int prot |
1097 | off, | | 1023 | off, |
1098 | prot, | | 1024 | prot, |
1099 | BUS_SPACE_MAP_LINEAR)); | | 1025 | BUS_SPACE_MAP_LINEAR)); |
1100 | } | | 1026 | } |
1101 | | | 1027 | |
1102 | off -= sc->sc_fb_psize; | | 1028 | off -= sc->sc_fb_psize; |
1103 | if (off < sc->sc_ctl_psize) { | | 1029 | if (off < sc->sc_ctl_psize) { |
1104 | return (bus_space_mmap(sc->sc_bustag, | | 1030 | return (bus_space_mmap(sc->sc_bustag, |
1105 | sc->sc_ctl_paddr, | | 1031 | sc->sc_ctl_paddr, |
1106 | off, | | 1032 | off, |
1107 | prot, | | 1033 | prot, |
1108 | BUS_SPACE_MAP_LINEAR)); | | 1034 | BUS_SPACE_MAP_LINEAR)); |
1109 | } | | 1035 | } |
1110 | #if 0 | | | |
1111 | off -= sc->sc_ctl_psize; | | | |
1112 | | | 1036 | |
1113 | return (bus_space_mmap(sc->sc_bustag, | | | |
1114 | sc->sc_cmd_paddr, | | | |
1115 | off, | | | |
1116 | prot, | | | |
1117 | BUS_SPACE_MAP_LINEAR)); | | | |
1118 | #endif | | | |
1119 | return EINVAL; | | 1037 | return EINVAL; |
1120 | } | | 1038 | } |
1121 | | | 1039 | |
1122 | /* wscons stuff */ | | 1040 | /* wscons stuff */ |
1123 | #if NWSDISPLAY > 0 | | 1041 | #if NWSDISPLAY > 0 |
1124 | | | 1042 | |
1125 | static void | | 1043 | static void |
1126 | p9100_cursor(void *cookie, int on, int row, int col) | | 1044 | p9100_cursor(void *cookie, int on, int row, int col) |
1127 | { | | 1045 | { |
1128 | struct rasops_info *ri = cookie; | | 1046 | struct rasops_info *ri = cookie; |
1129 | struct vcons_screen *scr = ri->ri_hw; | | 1047 | struct vcons_screen *scr = ri->ri_hw; |
1130 | struct p9100_softc *sc = scr->scr_cookie; | | 1048 | struct p9100_softc *sc = scr->scr_cookie; |
1131 | int x, y, wi,he; | | 1049 | int x, y, wi,he; |