use BUS_SPACE_MAP_LARGEdiff -r1.18 -r1.19 src/sys/dev/sbus/agten.c
(macallan)
--- src/sys/dev/sbus/agten.c 2009/05/12 13:20:05 1.18
+++ src/sys/dev/sbus/agten.c 2009/05/26 03:32:51 1.19
@@ -1,1080 +1,1081 @@ | @@ -1,1080 +1,1081 @@ | |||
1 | /* $NetBSD: agten.c,v 1.18 2009/05/12 13:20:05 cegger Exp $ */ | 1 | /* $NetBSD: agten.c,v 1.19 2009/05/26 03:32:51 macallan Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2007 Michael Lorenz | 4 | * Copyright (c) 2007 Michael Lorenz | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: agten.c,v 1.18 2009/05/12 13:20:05 cegger Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: agten.c,v 1.19 2009/05/26 03:32:51 macallan Exp $"); | |
31 | 31 | |||
32 | /* | 32 | /* | |
33 | * a driver for the Fujitsu AG-10e SBus framebuffer | 33 | * a driver for the Fujitsu AG-10e SBus framebuffer | |
34 | * | 34 | * | |
35 | * this thing is Frankenstein's Monster among graphics boards. | 35 | * this thing is Frankenstein's Monster among graphics boards. | |
36 | * it contains three graphics chips: | 36 | * it contains three graphics chips: | |
37 | * a GLint - 24bit stuff, double-buffered | 37 | * a GLint - 24bit stuff, double-buffered | |
38 | * an Imagine 128 which provides an 8bit overlay | 38 | * an Imagine 128 which provides an 8bit overlay | |
39 | * a Weitek P9100 which provides WIDs | 39 | * a Weitek P9100 which provides WIDs | |
40 | * so here we need to mess only with the P9100 and the I128 - for X we just | 40 | * so here we need to mess only with the P9100 and the I128 - for X we just | |
41 | * hide the overlay and let the Xserver mess with the GLint | 41 | * hide the overlay and let the Xserver mess with the GLint | |
42 | */ | 42 | */ | |
43 | 43 | |||
44 | #include <sys/param.h> | 44 | #include <sys/param.h> | |
45 | #include <sys/systm.h> | 45 | #include <sys/systm.h> | |
46 | #include <sys/kernel.h> | 46 | #include <sys/kernel.h> | |
47 | #include <sys/device.h> | 47 | #include <sys/device.h> | |
48 | #include <sys/proc.h> | 48 | #include <sys/proc.h> | |
49 | #include <sys/mutex.h> | 49 | #include <sys/mutex.h> | |
50 | #include <sys/ioctl.h> | 50 | #include <sys/ioctl.h> | |
51 | #include <sys/kernel.h> | 51 | #include <sys/kernel.h> | |
52 | #include <sys/systm.h> | 52 | #include <sys/systm.h> | |
53 | #include <sys/conf.h> | 53 | #include <sys/conf.h> | |
54 | 54 | |||
55 | #include <dev/sun/fbio.h> | 55 | #include <dev/sun/fbio.h> | |
56 | #include <dev/sun/fbvar.h> | 56 | #include <dev/sun/fbvar.h> | |
57 | #include <dev/sun/btreg.h> | 57 | #include <dev/sun/btreg.h> | |
58 | #include <dev/sun/btvar.h> | 58 | #include <dev/sun/btvar.h> | |
59 | 59 | |||
60 | #include <sys/bus.h> | 60 | #include <sys/bus.h> | |
61 | #include <machine/autoconf.h> | 61 | #include <machine/autoconf.h> | |
62 | 62 | |||
63 | #include <dev/sbus/sbusvar.h> | 63 | #include <dev/sbus/sbusvar.h> | |
64 | 64 | |||
65 | #include <dev/wscons/wsconsio.h> | 65 | #include <dev/wscons/wsconsio.h> | |
66 | #include <dev/wscons/wsdisplayvar.h> | 66 | #include <dev/wscons/wsdisplayvar.h> | |
67 | #include <dev/rasops/rasops.h> | 67 | #include <dev/rasops/rasops.h> | |
68 | #include <dev/wsfont/wsfont.h> | 68 | #include <dev/wsfont/wsfont.h> | |
69 | 69 | |||
70 | #include <dev/wscons/wsdisplay_vconsvar.h> | 70 | #include <dev/wscons/wsdisplay_vconsvar.h> | |
71 | 71 | |||
72 | #include <dev/sbus/p9100reg.h> | 72 | #include <dev/sbus/p9100reg.h> | |
73 | #include <dev/ic/ibm561reg.h> | 73 | #include <dev/ic/ibm561reg.h> | |
74 | #include <dev/ic/i128reg.h> | 74 | #include <dev/ic/i128reg.h> | |
75 | #include <dev/ic/i128var.h> | 75 | #include <dev/ic/i128var.h> | |
76 | 76 | |||
77 | #include "opt_agten.h" | 77 | #include "opt_agten.h" | |
78 | 78 | |||
79 | static int agten_match(device_t, cfdata_t, void *); | 79 | static int agten_match(device_t, cfdata_t, void *); | |
80 | static void agten_attach(device_t, device_t, void *); | 80 | static void agten_attach(device_t, device_t, void *); | |
81 | 81 | |||
82 | static int agten_ioctl(void *, void *, u_long, void *, int, struct lwp *); | 82 | static int agten_ioctl(void *, void *, u_long, void *, int, struct lwp *); | |
83 | static paddr_t agten_mmap(void *, void *, off_t, int); | 83 | static paddr_t agten_mmap(void *, void *, off_t, int); | |
84 | static void agten_init_screen(void *, struct vcons_screen *, int, long *); | 84 | static void agten_init_screen(void *, struct vcons_screen *, int, long *); | |
85 | 85 | |||
86 | struct agten_softc { | 86 | struct agten_softc { | |
87 | device_t sc_dev; /* base device */ | 87 | device_t sc_dev; /* base device */ | |
88 | struct sbusdev sc_sd; /* sbus device */ | 88 | struct sbusdev sc_sd; /* sbus device */ | |
89 | struct fbdevice sc_fb; /* frame buffer device */ | 89 | struct fbdevice sc_fb; /* frame buffer device */ | |
90 | 90 | |||
91 | struct vcons_screen sc_console_screen; | 91 | struct vcons_screen sc_console_screen; | |
92 | struct wsscreen_descr sc_defaultscreen_descr; | 92 | struct wsscreen_descr sc_defaultscreen_descr; | |
93 | const struct wsscreen_descr *sc_screens[1]; | 93 | const struct wsscreen_descr *sc_screens[1]; | |
94 | struct wsscreen_list sc_screenlist; | 94 | struct wsscreen_list sc_screenlist; | |
95 | 95 | |||
96 | bus_space_tag_t sc_bustag; | 96 | bus_space_tag_t sc_bustag; | |
97 | 97 | |||
98 | bus_space_handle_t sc_i128_fbh; | 98 | bus_space_handle_t sc_i128_fbh; | |
99 | bus_size_t sc_i128_fbsz; | 99 | bus_size_t sc_i128_fbsz; | |
100 | bus_space_handle_t sc_i128_regh; | 100 | bus_space_handle_t sc_i128_regh; | |
101 | bus_space_handle_t sc_p9100_regh; | 101 | bus_space_handle_t sc_p9100_regh; | |
102 | bus_addr_t sc_glint_fb; | 102 | bus_addr_t sc_glint_fb; | |
103 | bus_addr_t sc_glint_regs; | 103 | bus_addr_t sc_glint_regs; | |
104 | uint32_t sc_glint_fbsz; | 104 | uint32_t sc_glint_fbsz; | |
105 | 105 | |||
106 | uint32_t sc_width; | 106 | uint32_t sc_width; | |
107 | uint32_t sc_height; /* panel width / height */ | 107 | uint32_t sc_height; /* panel width / height */ | |
108 | uint32_t sc_stride; | 108 | uint32_t sc_stride; | |
109 | uint32_t sc_depth; | 109 | uint32_t sc_depth; | |
110 | 110 | |||
111 | int sc_cursor_x; | 111 | int sc_cursor_x; | |
112 | int sc_cursor_y; | 112 | int sc_cursor_y; | |
113 | int sc_video; /* video output enabled */ | 113 | int sc_video; /* video output enabled */ | |
114 | 114 | |||
115 | /* some /dev/fb* stuff */ | 115 | /* some /dev/fb* stuff */ | |
116 | int sc_fb_is_open; | 116 | int sc_fb_is_open; | |
117 | 117 | |||
118 | union bt_cmap sc_cmap; /* Brooktree color map */ | 118 | union bt_cmap sc_cmap; /* Brooktree color map */ | |
119 | 119 | |||
120 | int sc_mode; | 120 | int sc_mode; | |
121 | uint32_t sc_bg; | 121 | uint32_t sc_bg; | |
122 | struct vcons_data vd; | 122 | struct vcons_data vd; | |
123 | }; | 123 | }; | |
124 | 124 | |||
125 | CFATTACH_DECL_NEW(agten, sizeof(struct agten_softc), | 125 | CFATTACH_DECL_NEW(agten, sizeof(struct agten_softc), | |
126 | agten_match, agten_attach, NULL, NULL); | 126 | agten_match, agten_attach, NULL, NULL); | |
127 | 127 | |||
128 | 128 | |||
129 | static int agten_putcmap(struct agten_softc *, struct wsdisplay_cmap *); | 129 | static int agten_putcmap(struct agten_softc *, struct wsdisplay_cmap *); | |
130 | static int agten_getcmap(struct agten_softc *, struct wsdisplay_cmap *); | 130 | static int agten_getcmap(struct agten_softc *, struct wsdisplay_cmap *); | |
131 | static int agten_putpalreg(struct agten_softc *, uint8_t, uint8_t, | 131 | static int agten_putpalreg(struct agten_softc *, uint8_t, uint8_t, | |
132 | uint8_t, uint8_t); | 132 | uint8_t, uint8_t); | |
133 | static void agten_init(struct agten_softc *); | 133 | static void agten_init(struct agten_softc *); | |
134 | static void agten_gfx(struct agten_softc *); | 134 | static void agten_gfx(struct agten_softc *); | |
135 | static void agten_set_video(struct agten_softc *, int); | 135 | static void agten_set_video(struct agten_softc *, int); | |
136 | static int agten_get_video(struct agten_softc *); | 136 | static int agten_get_video(struct agten_softc *); | |
137 | 137 | |||
138 | static void agten_copycols(void *, int, int, int, int); | 138 | static void agten_copycols(void *, int, int, int, int); | |
139 | static void agten_erasecols(void *, int, int, int, long); | 139 | static void agten_erasecols(void *, int, int, int, long); | |
140 | static void agten_copyrows(void *, int, int, int); | 140 | static void agten_copyrows(void *, int, int, int); | |
141 | static void agten_eraserows(void *, int, int, long); | 141 | static void agten_eraserows(void *, int, int, long); | |
142 | 142 | |||
143 | static void agten_move_cursor(struct agten_softc *, int, int); | 143 | static void agten_move_cursor(struct agten_softc *, int, int); | |
144 | static int agten_do_cursor(struct agten_softc *sc, | 144 | static int agten_do_cursor(struct agten_softc *sc, | |
145 | struct wsdisplay_cursor *); | 145 | struct wsdisplay_cursor *); | |
146 | static int agten_do_sun_cursor(struct agten_softc *sc, | 146 | static int agten_do_sun_cursor(struct agten_softc *sc, | |
147 | struct fbcursor *); | 147 | struct fbcursor *); | |
148 | 148 | |||
149 | static uint16_t util_interleave(uint8_t, uint8_t); | 149 | static uint16_t util_interleave(uint8_t, uint8_t); | |
150 | static uint16_t util_interleave_lin(uint8_t, uint8_t); | 150 | static uint16_t util_interleave_lin(uint8_t, uint8_t); | |
151 | 151 | |||
152 | extern const u_char rasops_cmap[768]; | 152 | extern const u_char rasops_cmap[768]; | |
153 | 153 | |||
154 | struct wsdisplay_accessops agten_accessops = { | 154 | struct wsdisplay_accessops agten_accessops = { | |
155 | agten_ioctl, | 155 | agten_ioctl, | |
156 | agten_mmap, | 156 | agten_mmap, | |
157 | NULL, /* alloc_screen */ | 157 | NULL, /* alloc_screen */ | |
158 | NULL, /* free_screen */ | 158 | NULL, /* free_screen */ | |
159 | NULL, /* show_screen */ | 159 | NULL, /* show_screen */ | |
160 | NULL, /* load_font */ | 160 | NULL, /* load_font */ | |
161 | NULL, /* pollc */ | 161 | NULL, /* pollc */ | |
162 | NULL /* scroll */ | 162 | NULL /* scroll */ | |
163 | }; | 163 | }; | |
164 | 164 | |||
165 | /* /dev/fb* stuff */ | 165 | /* /dev/fb* stuff */ | |
166 | extern struct cfdriver agten_cd; | 166 | extern struct cfdriver agten_cd; | |
167 | 167 | |||
168 | static int agten_fb_open(dev_t, int, int, struct lwp *); | 168 | static int agten_fb_open(dev_t, int, int, struct lwp *); | |
169 | static int agten_fb_close(dev_t, int, int, struct lwp *); | 169 | static int agten_fb_close(dev_t, int, int, struct lwp *); | |
170 | static int agten_fb_ioctl(dev_t, u_long, void *, int, struct lwp *); | 170 | static int agten_fb_ioctl(dev_t, u_long, void *, int, struct lwp *); | |
171 | static paddr_t agten_fb_mmap(dev_t, off_t, int); | 171 | static paddr_t agten_fb_mmap(dev_t, off_t, int); | |
172 | static void agten_fb_unblank(device_t); | 172 | static void agten_fb_unblank(device_t); | |
173 | 173 | |||
174 | static struct fbdriver agtenfbdriver = { | 174 | static struct fbdriver agtenfbdriver = { | |
175 | agten_fb_unblank, agten_fb_open, agten_fb_close, agten_fb_ioctl, | 175 | agten_fb_unblank, agten_fb_open, agten_fb_close, agten_fb_ioctl, | |
176 | nopoll, agten_fb_mmap, nokqfilter | 176 | nopoll, agten_fb_mmap, nokqfilter | |
177 | }; | 177 | }; | |
178 | 178 | |||
179 | static inline void | 179 | static inline void | |
180 | agten_write_dac(struct agten_softc *sc, int reg, uint8_t val) | 180 | agten_write_dac(struct agten_softc *sc, int reg, uint8_t val) | |
181 | { | 181 | { | |
182 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, | 182 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, | |
183 | 0x200 + (reg << 2), (uint32_t)val << 16); | 183 | 0x200 + (reg << 2), (uint32_t)val << 16); | |
184 | } | 184 | } | |
185 | 185 | |||
186 | static inline void | 186 | static inline void | |
187 | agten_write_idx(struct agten_softc *sc, int offset) | 187 | agten_write_idx(struct agten_softc *sc, int offset) | |
188 | { | 188 | { | |
189 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, | 189 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, | |
190 | 0x200 + (IBM561_ADDR_LOW << 2), (offset & 0xff) << 16); | 190 | 0x200 + (IBM561_ADDR_LOW << 2), (offset & 0xff) << 16); | |
191 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, | 191 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, | |
192 | 0x200 + (IBM561_ADDR_HIGH << 2), ((offset >> 8) & 0xff) << 16); | 192 | 0x200 + (IBM561_ADDR_HIGH << 2), ((offset >> 8) & 0xff) << 16); | |
193 | } | 193 | } | |
194 | 194 | |||
195 | static inline void | 195 | static inline void | |
196 | agten_write_dac_10(struct agten_softc *sc, int reg, uint16_t val) | 196 | agten_write_dac_10(struct agten_softc *sc, int reg, uint16_t val) | |
197 | { | 197 | { | |
198 | agten_write_dac(sc, reg, (val >> 2) & 0xff); | 198 | agten_write_dac(sc, reg, (val >> 2) & 0xff); | |
199 | agten_write_dac(sc, reg, (val & 0x3) << 6); | 199 | agten_write_dac(sc, reg, (val & 0x3) << 6); | |
200 | } | 200 | } | |
201 | 201 | |||
202 | static int | 202 | static int | |
203 | agten_match(device_t dev, cfdata_t cf, void *aux) | 203 | agten_match(device_t dev, cfdata_t cf, void *aux) | |
204 | { | 204 | { | |
205 | struct sbus_attach_args *sa = aux; | 205 | struct sbus_attach_args *sa = aux; | |
206 | 206 | |||
207 | if (strcmp("PFU,aga", sa->sa_name) == 0) | 207 | if (strcmp("PFU,aga", sa->sa_name) == 0) | |
208 | return 100; | 208 | return 100; | |
209 | return 0; | 209 | return 0; | |
210 | } | 210 | } | |
211 | 211 | |||
212 | static void | 212 | static void | |
213 | agten_attach(device_t parent, device_t dev, void *aux) | 213 | agten_attach(device_t parent, device_t dev, void *aux) | |
214 | { | 214 | { | |
215 | struct agten_softc *sc = device_private(dev); | 215 | struct agten_softc *sc = device_private(dev); | |
216 | struct sbus_attach_args *sa = aux; | 216 | struct sbus_attach_args *sa = aux; | |
217 | struct fbdevice *fb = &sc->sc_fb; | 217 | struct fbdevice *fb = &sc->sc_fb; | |
218 | struct wsemuldisplaydev_attach_args aa; | 218 | struct wsemuldisplaydev_attach_args aa; | |
219 | struct rasops_info *ri; | 219 | struct rasops_info *ri; | |
220 | long defattr; | 220 | long defattr; | |
221 | uint32_t reg; | 221 | uint32_t reg; | |
222 | int node = sa->sa_node; | 222 | int node = sa->sa_node; | |
223 | int console; | 223 | int console; | |
224 | 224 | |||
225 | sc->sc_dev = dev; | 225 | sc->sc_dev = dev; | |
226 | sc->sc_defaultscreen_descr = (struct wsscreen_descr){ | 226 | sc->sc_defaultscreen_descr = (struct wsscreen_descr){ | |
227 | "default", | 227 | "default", | |
228 | 0, 0, | 228 | 0, 0, | |
229 | NULL, | 229 | NULL, | |
230 | 8, 16, | 230 | 8, 16, | |
231 | WSSCREEN_WSCOLORS | WSSCREEN_HILIT, | 231 | WSSCREEN_WSCOLORS | WSSCREEN_HILIT, | |
232 | NULL | 232 | NULL | |
233 | }; | 233 | }; | |
234 | sc->sc_screens[0] = &sc->sc_defaultscreen_descr; | 234 | sc->sc_screens[0] = &sc->sc_defaultscreen_descr; | |
235 | sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; | 235 | sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; | |
236 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | 236 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | |
237 | sc->sc_fb_is_open = 0; | 237 | sc->sc_fb_is_open = 0; | |
238 | sc->sc_video = -1; | 238 | sc->sc_video = -1; | |
239 | sc->sc_bustag = sa->sa_bustag; | 239 | sc->sc_bustag = sa->sa_bustag; | |
240 | 240 | |||
241 | sc->sc_width = prom_getpropint(node, "ffb_width", 1152); | 241 | sc->sc_width = prom_getpropint(node, "ffb_width", 1152); | |
242 | sc->sc_height = prom_getpropint(node, "ffb_height", 900); | 242 | sc->sc_height = prom_getpropint(node, "ffb_height", 900); | |
243 | sc->sc_depth = prom_getpropint(node, "ffb_depth", 8); | 243 | sc->sc_depth = prom_getpropint(node, "ffb_depth", 8); | |
244 | sc->sc_stride = sc->sc_width * (sc->sc_depth >> 3); | 244 | sc->sc_stride = sc->sc_width * (sc->sc_depth >> 3); | |
245 | 245 | |||
246 | reg = prom_getpropint(node, "i128_fb_physaddr", -1); | 246 | reg = prom_getpropint(node, "i128_fb_physaddr", -1); | |
247 | sc->sc_i128_fbsz = prom_getpropint(node, "i128_fb_size", -1); | 247 | sc->sc_i128_fbsz = prom_getpropint(node, "i128_fb_size", -1); | |
248 | if (sparc_bus_map_large(sc->sc_bustag, | 248 | if (sbus_bus_map(sc->sc_bustag, | |
249 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg, | 249 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg, | |
250 | sc->sc_stride * sc->sc_height, BUS_SPACE_MAP_LINEAR, | 250 | sc->sc_stride * sc->sc_height, | |
251 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, | |||
251 | &sc->sc_i128_fbh) != 0) { | 252 | &sc->sc_i128_fbh) != 0) { | |
252 | 253 | |||
253 | aprint_error_dev(dev, "unable to map the framebuffer\n"); | 254 | aprint_error_dev(dev, "unable to map the framebuffer\n"); | |
254 | return; | 255 | return; | |
255 | } | 256 | } | |
256 | fb->fb_pixels = bus_space_vaddr(sc->sc_bustag, sc->sc_i128_fbh); | 257 | fb->fb_pixels = bus_space_vaddr(sc->sc_bustag, sc->sc_i128_fbh); | |
257 | 258 | |||
258 | reg = prom_getpropint(node, "i128_reg_physaddr", -1); | 259 | reg = prom_getpropint(node, "i128_reg_physaddr", -1); | |
259 | if (sbus_bus_map(sc->sc_bustag, | 260 | if (sbus_bus_map(sc->sc_bustag, | |
260 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg, | 261 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg, | |
261 | 0x10000, 0, &sc->sc_i128_regh) != 0) { | 262 | 0x10000, 0, &sc->sc_i128_regh) != 0) { | |
262 | 263 | |||
263 | aprint_error_dev(dev, "unable to map I128 registers\n"); | 264 | aprint_error_dev(dev, "unable to map I128 registers\n"); | |
264 | return; | 265 | return; | |
265 | } | 266 | } | |
266 | 267 | |||
267 | reg = prom_getpropint(node, "p9100_reg_physaddr", -1); | 268 | reg = prom_getpropint(node, "p9100_reg_physaddr", -1); | |
268 | if (sbus_bus_map(sc->sc_bustag, | 269 | if (sbus_bus_map(sc->sc_bustag, | |
269 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg, | 270 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg, | |
270 | 0x8000, 0, &sc->sc_p9100_regh) != 0) { | 271 | 0x8000, 0, &sc->sc_p9100_regh) != 0) { | |
271 | 272 | |||
272 | aprint_error_dev(dev, "unable to map P9100 registers\n"); | 273 | aprint_error_dev(dev, "unable to map P9100 registers\n"); | |
273 | return; | 274 | return; | |
274 | } | 275 | } | |
275 | 276 | |||
276 | reg = prom_getpropint(node, "glint_fb0_physaddr", -1); | 277 | reg = prom_getpropint(node, "glint_fb0_physaddr", -1); | |
277 | sc->sc_glint_fb = sbus_bus_addr(sc->sc_bustag, | 278 | sc->sc_glint_fb = sbus_bus_addr(sc->sc_bustag, | |
278 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg); | 279 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg); | |
279 | sc->sc_glint_fbsz = prom_getpropint(node, "glint_lb_size", -1); | 280 | sc->sc_glint_fbsz = prom_getpropint(node, "glint_lb_size", -1); | |
280 | reg = prom_getpropint(node, "glint_reg_physaddr", -1); | 281 | reg = prom_getpropint(node, "glint_reg_physaddr", -1); | |
281 | sc->sc_glint_regs = sbus_bus_addr(sc->sc_bustag, | 282 | sc->sc_glint_regs = sbus_bus_addr(sc->sc_bustag, | |
282 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg); | 283 | sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base + reg); | |
283 | 284 | |||
284 | sbus_establish(&sc->sc_sd, sc->sc_dev); | 285 | sbus_establish(&sc->sc_sd, sc->sc_dev); | |
285 | 286 | |||
286 | #if 0 | 287 | #if 0 | |
287 | bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO, | 288 | bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO, | |
288 | agten_intr, sc); | 289 | agten_intr, sc); | |
289 | #endif | 290 | #endif | |
290 | 291 | |||
291 | printf(": %dx%d\n", sc->sc_width, sc->sc_height); | 292 | printf(": %dx%d\n", sc->sc_width, sc->sc_height); | |
292 | agten_init(sc); | 293 | agten_init(sc); | |
293 | 294 | |||
294 | console = fb_is_console(node); | 295 | console = fb_is_console(node); | |
295 | 296 | |||
296 | vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, | 297 | vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, | |
297 | &agten_accessops); | 298 | &agten_accessops); | |
298 | sc->vd.init_screen = agten_init_screen; | 299 | sc->vd.init_screen = agten_init_screen; | |
299 | 300 | |||
300 | ri = &sc->sc_console_screen.scr_ri; | 301 | ri = &sc->sc_console_screen.scr_ri; | |
301 | 302 | |||
302 | if (console) { | 303 | if (console) { | |
303 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, | 304 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, | |
304 | &defattr); | 305 | &defattr); | |
305 | sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | 306 | sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | |
306 | 307 | |||
307 | sc->sc_defaultscreen_descr.textops = &ri->ri_ops; | 308 | sc->sc_defaultscreen_descr.textops = &ri->ri_ops; | |
308 | sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; | 309 | sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; | |
309 | sc->sc_defaultscreen_descr.nrows = ri->ri_rows; | 310 | sc->sc_defaultscreen_descr.nrows = ri->ri_rows; | |
310 | sc->sc_defaultscreen_descr.ncols = ri->ri_cols; | 311 | sc->sc_defaultscreen_descr.ncols = ri->ri_cols; | |
311 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, | 312 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, | |
312 | defattr); | 313 | defattr); | |
313 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, 0, 0, | 314 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, 0, 0, | |
314 | sc->sc_width, sc->sc_height, | 315 | sc->sc_width, sc->sc_height, | |
315 | ri->ri_devcmap[(defattr >> 16) & 0xff]); | 316 | ri->ri_devcmap[(defattr >> 16) & 0xff]); | |
316 | } else { | 317 | } else { | |
317 | /* | 318 | /* | |
318 | * since we're not the console we can postpone the rest | 319 | * since we're not the console we can postpone the rest | |
319 | * until someone actually allocates a screen for us | 320 | * until someone actually allocates a screen for us | |
320 | */ | 321 | */ | |
321 | } | 322 | } | |
322 | 323 | |||
323 | /* Initialize the default color map. */ | 324 | /* Initialize the default color map. */ | |
324 | 325 | |||
325 | aa.console = console; | 326 | aa.console = console; | |
326 | aa.scrdata = &sc->sc_screenlist; | 327 | aa.scrdata = &sc->sc_screenlist; | |
327 | aa.accessops = &agten_accessops; | 328 | aa.accessops = &agten_accessops; | |
328 | aa.accesscookie = &sc->vd; | 329 | aa.accesscookie = &sc->vd; | |
329 | 330 | |||
330 | config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); | 331 | config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); | |
331 | 332 | |||
332 | fb->fb_driver = &agtenfbdriver; | 333 | fb->fb_driver = &agtenfbdriver; | |
333 | fb->fb_device = sc->sc_dev; | 334 | fb->fb_device = sc->sc_dev; | |
334 | fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; | 335 | fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; | |
335 | fb->fb_type.fb_type = FBTYPE_AG10E; | 336 | fb->fb_type.fb_type = FBTYPE_AG10E; | |
336 | fb->fb_type.fb_cmsize = 256; /* doesn't matter, we're always 24bit */ | 337 | fb->fb_type.fb_cmsize = 256; /* doesn't matter, we're always 24bit */ | |
337 | fb->fb_type.fb_size = sc->sc_glint_fbsz; | 338 | fb->fb_type.fb_size = sc->sc_glint_fbsz; | |
338 | fb->fb_type.fb_width = sc->sc_width; | 339 | fb->fb_type.fb_width = sc->sc_width; | |
339 | fb->fb_type.fb_height = sc->sc_height; | 340 | fb->fb_type.fb_height = sc->sc_height; | |
340 | fb->fb_type.fb_depth = 32; | 341 | fb->fb_type.fb_depth = 32; | |
341 | fb->fb_linebytes = sc->sc_stride << 2; | 342 | fb->fb_linebytes = sc->sc_stride << 2; | |
342 | fb_attach(fb, console); | 343 | fb_attach(fb, console); | |
343 | agten_set_video(sc, 1); /* make sure video's on */ | 344 | agten_set_video(sc, 1); /* make sure video's on */ | |
344 | } | 345 | } | |
345 | 346 | |||
346 | static int | 347 | static int | |
347 | agten_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, | 348 | agten_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, | |
348 | struct lwp *l) | 349 | struct lwp *l) | |
349 | { | 350 | { | |
350 | struct vcons_data *vd = v; | 351 | struct vcons_data *vd = v; | |
351 | struct agten_softc *sc = vd->cookie; | 352 | struct agten_softc *sc = vd->cookie; | |
352 | struct wsdisplay_fbinfo *wdf; | 353 | struct wsdisplay_fbinfo *wdf; | |
353 | struct vcons_screen *ms = vd->active; | 354 | struct vcons_screen *ms = vd->active; | |
354 | 355 | |||
355 | switch (cmd) { | 356 | switch (cmd) { | |
356 | 357 | |||
357 | case WSDISPLAYIO_GTYPE: | 358 | case WSDISPLAYIO_GTYPE: | |
358 | *(u_int *)data = WSDISPLAY_TYPE_AG10; | 359 | *(u_int *)data = WSDISPLAY_TYPE_AG10; | |
359 | return 0; | 360 | return 0; | |
360 | 361 | |||
361 | case WSDISPLAYIO_GINFO: | 362 | case WSDISPLAYIO_GINFO: | |
362 | if (ms == NULL) | 363 | if (ms == NULL) | |
363 | return ENODEV; | 364 | return ENODEV; | |
364 | wdf = (void *)data; | 365 | wdf = (void *)data; | |
365 | wdf->height = ms->scr_ri.ri_height; | 366 | wdf->height = ms->scr_ri.ri_height; | |
366 | wdf->width = ms->scr_ri.ri_width; | 367 | wdf->width = ms->scr_ri.ri_width; | |
367 | wdf->depth = 32; | 368 | wdf->depth = 32; | |
368 | wdf->cmsize = 256; | 369 | wdf->cmsize = 256; | |
369 | return 0; | 370 | return 0; | |
370 | 371 | |||
371 | case WSDISPLAYIO_GVIDEO: | 372 | case WSDISPLAYIO_GVIDEO: | |
372 | *(int *)data = sc->sc_video; | 373 | *(int *)data = sc->sc_video; | |
373 | return 0; | 374 | return 0; | |
374 | 375 | |||
375 | case WSDISPLAYIO_SVIDEO: | 376 | case WSDISPLAYIO_SVIDEO: | |
376 | agten_set_video(sc, *(int *)data); | 377 | agten_set_video(sc, *(int *)data); | |
377 | return 0; | 378 | return 0; | |
378 | 379 | |||
379 | case WSDISPLAYIO_GETCMAP: | 380 | case WSDISPLAYIO_GETCMAP: | |
380 | return agten_getcmap(sc, | 381 | return agten_getcmap(sc, | |
381 | (struct wsdisplay_cmap *)data); | 382 | (struct wsdisplay_cmap *)data); | |
382 | 383 | |||
383 | case WSDISPLAYIO_PUTCMAP: | 384 | case WSDISPLAYIO_PUTCMAP: | |
384 | return agten_putcmap(sc, | 385 | return agten_putcmap(sc, | |
385 | (struct wsdisplay_cmap *)data); | 386 | (struct wsdisplay_cmap *)data); | |
386 | 387 | |||
387 | case WSDISPLAYIO_LINEBYTES: | 388 | case WSDISPLAYIO_LINEBYTES: | |
388 | *(u_int *)data = sc->sc_stride << 2; | 389 | *(u_int *)data = sc->sc_stride << 2; | |
389 | return 0; | 390 | return 0; | |
390 | 391 | |||
391 | case WSDISPLAYIO_SMODE: | 392 | case WSDISPLAYIO_SMODE: | |
392 | { | 393 | { | |
393 | int new_mode = *(int*)data; | 394 | int new_mode = *(int*)data; | |
394 | if (new_mode != sc->sc_mode) { | 395 | if (new_mode != sc->sc_mode) { | |
395 | sc->sc_mode = new_mode; | 396 | sc->sc_mode = new_mode; | |
396 | if(new_mode == WSDISPLAYIO_MODE_EMUL) { | 397 | if(new_mode == WSDISPLAYIO_MODE_EMUL) { | |
397 | agten_init(sc); | 398 | agten_init(sc); | |
398 | vcons_redraw_screen(ms); | 399 | vcons_redraw_screen(ms); | |
399 | } else { | 400 | } else { | |
400 | agten_gfx(sc); | 401 | agten_gfx(sc); | |
401 | } | 402 | } | |
402 | } | 403 | } | |
403 | } | 404 | } | |
404 | return 0; | 405 | return 0; | |
405 | 406 | |||
406 | case WSDISPLAYIO_GCURPOS: | 407 | case WSDISPLAYIO_GCURPOS: | |
407 | { | 408 | { | |
408 | struct wsdisplay_curpos *cp = (void *)data; | 409 | struct wsdisplay_curpos *cp = (void *)data; | |
409 | 410 | |||
410 | cp->x = sc->sc_cursor_x; | 411 | cp->x = sc->sc_cursor_x; | |
411 | cp->y = sc->sc_cursor_y; | 412 | cp->y = sc->sc_cursor_y; | |
412 | } | 413 | } | |
413 | return 0; | 414 | return 0; | |
414 | 415 | |||
415 | case WSDISPLAYIO_SCURPOS: | 416 | case WSDISPLAYIO_SCURPOS: | |
416 | { | 417 | { | |
417 | struct wsdisplay_curpos *cp = (void *)data; | 418 | struct wsdisplay_curpos *cp = (void *)data; | |
418 | 419 | |||
419 | agten_move_cursor(sc, cp->x, cp->y); | 420 | agten_move_cursor(sc, cp->x, cp->y); | |
420 | } | 421 | } | |
421 | return 0; | 422 | return 0; | |
422 | 423 | |||
423 | case WSDISPLAYIO_GCURMAX: | 424 | case WSDISPLAYIO_GCURMAX: | |
424 | { | 425 | { | |
425 | struct wsdisplay_curpos *cp = (void *)data; | 426 | struct wsdisplay_curpos *cp = (void *)data; | |
426 | 427 | |||
427 | cp->x = 64; | 428 | cp->x = 64; | |
428 | cp->y = 64; | 429 | cp->y = 64; | |
429 | } | 430 | } | |
430 | return 0; | 431 | return 0; | |
431 | 432 | |||
432 | case WSDISPLAYIO_SCURSOR: | 433 | case WSDISPLAYIO_SCURSOR: | |
433 | { | 434 | { | |
434 | struct wsdisplay_cursor *cursor = (void *)data; | 435 | struct wsdisplay_cursor *cursor = (void *)data; | |
435 | 436 | |||
436 | return agten_do_cursor(sc, cursor); | 437 | return agten_do_cursor(sc, cursor); | |
437 | } | 438 | } | |
438 | } | 439 | } | |
439 | return EPASSTHROUGH; | 440 | return EPASSTHROUGH; | |
440 | } | 441 | } | |
441 | 442 | |||
442 | static paddr_t | 443 | static paddr_t | |
443 | agten_mmap(void *v, void *vs, off_t offset, int prot) | 444 | agten_mmap(void *v, void *vs, off_t offset, int prot) | |
444 | { | 445 | { | |
445 | struct vcons_data *vd = v; | 446 | struct vcons_data *vd = v; | |
446 | struct agten_softc *sc = vd->cookie; | 447 | struct agten_softc *sc = vd->cookie; | |
447 | 448 | |||
448 | if (offset < sc->sc_glint_fbsz) | 449 | if (offset < sc->sc_glint_fbsz) | |
449 | return bus_space_mmap(sc->sc_bustag, sc->sc_glint_fb, offset, | 450 | return bus_space_mmap(sc->sc_bustag, sc->sc_glint_fb, offset, | |
450 | prot, BUS_SPACE_MAP_LINEAR); | 451 | prot, BUS_SPACE_MAP_LINEAR); | |
451 | return -1; | 452 | return -1; | |
452 | } | 453 | } | |
453 | 454 | |||
454 | static void | 455 | static void | |
455 | agten_init_screen(void *cookie, struct vcons_screen *scr, | 456 | agten_init_screen(void *cookie, struct vcons_screen *scr, | |
456 | int existing, long *defattr) | 457 | int existing, long *defattr) | |
457 | { | 458 | { | |
458 | struct agten_softc *sc = cookie; | 459 | struct agten_softc *sc = cookie; | |
459 | struct rasops_info *ri = &scr->scr_ri; | 460 | struct rasops_info *ri = &scr->scr_ri; | |
460 | 461 | |||
461 | ri->ri_depth = sc->sc_depth; | 462 | ri->ri_depth = sc->sc_depth; | |
462 | ri->ri_width = sc->sc_width; | 463 | ri->ri_width = sc->sc_width; | |
463 | ri->ri_height = sc->sc_height; | 464 | ri->ri_height = sc->sc_height; | |
464 | ri->ri_stride = sc->sc_stride; | 465 | ri->ri_stride = sc->sc_stride; | |
465 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; | 466 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; | |
466 | 467 | |||
467 | ri->ri_bits = (char *)sc->sc_fb.fb_pixels; | 468 | ri->ri_bits = (char *)sc->sc_fb.fb_pixels; | |
468 | 469 | |||
469 | if (existing) { | 470 | if (existing) { | |
470 | ri->ri_flg |= RI_CLEAR; | 471 | ri->ri_flg |= RI_CLEAR; | |
471 | } | 472 | } | |
472 | 473 | |||
473 | rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); | 474 | rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); | |
474 | ri->ri_caps = WSSCREEN_WSCOLORS; | 475 | ri->ri_caps = WSSCREEN_WSCOLORS; | |
475 | 476 | |||
476 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, | 477 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, | |
477 | sc->sc_width / ri->ri_font->fontwidth); | 478 | sc->sc_width / ri->ri_font->fontwidth); | |
478 | 479 | |||
479 | ri->ri_hw = scr; | 480 | ri->ri_hw = scr; | |
480 | ri->ri_ops.copyrows = agten_copyrows; | 481 | ri->ri_ops.copyrows = agten_copyrows; | |
481 | ri->ri_ops.eraserows = agten_eraserows; | 482 | ri->ri_ops.eraserows = agten_eraserows; | |
482 | ri->ri_ops.copycols = agten_copycols; | 483 | ri->ri_ops.copycols = agten_copycols; | |
483 | ri->ri_ops.erasecols = agten_erasecols; | 484 | ri->ri_ops.erasecols = agten_erasecols; | |
484 | 485 | |||
485 | } | 486 | } | |
486 | 487 | |||
487 | static int | 488 | static int | |
488 | agten_putcmap(struct agten_softc *sc, struct wsdisplay_cmap *cm) | 489 | agten_putcmap(struct agten_softc *sc, struct wsdisplay_cmap *cm) | |
489 | { | 490 | { | |
490 | u_int index = cm->index; | 491 | u_int index = cm->index; | |
491 | u_int count = cm->count; | 492 | u_int count = cm->count; | |
492 | int i, error; | 493 | int i, error; | |
493 | u_char rbuf[256], gbuf[256], bbuf[256]; | 494 | u_char rbuf[256], gbuf[256], bbuf[256]; | |
494 | u_char *r, *g, *b; | 495 | u_char *r, *g, *b; | |
495 | 496 | |||
496 | if (cm->index >= 256 || cm->count > 256 || | 497 | if (cm->index >= 256 || cm->count > 256 || | |
497 | (cm->index + cm->count) > 256) | 498 | (cm->index + cm->count) > 256) | |
498 | return EINVAL; | 499 | return EINVAL; | |
499 | error = copyin(cm->red, &rbuf[index], count); | 500 | error = copyin(cm->red, &rbuf[index], count); | |
500 | if (error) | 501 | if (error) | |
501 | return error; | 502 | return error; | |
502 | error = copyin(cm->green, &gbuf[index], count); | 503 | error = copyin(cm->green, &gbuf[index], count); | |
503 | if (error) | 504 | if (error) | |
504 | return error; | 505 | return error; | |
505 | error = copyin(cm->blue, &bbuf[index], count); | 506 | error = copyin(cm->blue, &bbuf[index], count); | |
506 | if (error) | 507 | if (error) | |
507 | return error; | 508 | return error; | |
508 | 509 | |||
509 | r = &rbuf[index]; | 510 | r = &rbuf[index]; | |
510 | g = &gbuf[index]; | 511 | g = &gbuf[index]; | |
511 | b = &bbuf[index]; | 512 | b = &bbuf[index]; | |
512 | 513 | |||
513 | for (i = 0; i < count; i++) { | 514 | for (i = 0; i < count; i++) { | |
514 | agten_putpalreg(sc, index, *r, *g, *b); | 515 | agten_putpalreg(sc, index, *r, *g, *b); | |
515 | index++; | 516 | index++; | |
516 | r++, g++, b++; | 517 | r++, g++, b++; | |
517 | } | 518 | } | |
518 | return 0; | 519 | return 0; | |
519 | } | 520 | } | |
520 | 521 | |||
521 | static int | 522 | static int | |
522 | agten_getcmap(struct agten_softc *sc, struct wsdisplay_cmap *cm) | 523 | agten_getcmap(struct agten_softc *sc, struct wsdisplay_cmap *cm) | |
523 | { | 524 | { | |
524 | u_int index = cm->index; | 525 | u_int index = cm->index; | |
525 | u_int count = cm->count; | 526 | u_int count = cm->count; | |
526 | int error, i; | 527 | int error, i; | |
527 | uint8_t red[256], green[256], blue[256]; | 528 | uint8_t red[256], green[256], blue[256]; | |
528 | 529 | |||
529 | if (index >= 255 || count > 256 || index + count > 256) | 530 | if (index >= 255 || count > 256 || index + count > 256) | |
530 | return EINVAL; | 531 | return EINVAL; | |
531 | 532 | |||
532 | i = index; | 533 | i = index; | |
533 | while (i < (index + count)) { | 534 | while (i < (index + count)) { | |
534 | red[i] = sc->sc_cmap.cm_map[i][0]; | 535 | red[i] = sc->sc_cmap.cm_map[i][0]; | |
535 | green[i] = sc->sc_cmap.cm_map[i][1]; | 536 | green[i] = sc->sc_cmap.cm_map[i][1]; | |
536 | blue[i] = sc->sc_cmap.cm_map[i][2]; | 537 | blue[i] = sc->sc_cmap.cm_map[i][2]; | |
537 | i++; | 538 | i++; | |
538 | } | 539 | } | |
539 | error = copyout(&red[index], cm->red, count); | 540 | error = copyout(&red[index], cm->red, count); | |
540 | if (error) | 541 | if (error) | |
541 | return error; | 542 | return error; | |
542 | error = copyout(&green[index], cm->green, count); | 543 | error = copyout(&green[index], cm->green, count); | |
543 | if (error) | 544 | if (error) | |
544 | return error; | 545 | return error; | |
545 | error = copyout(&blue[index], cm->blue, count); | 546 | error = copyout(&blue[index], cm->blue, count); | |
546 | if (error) | 547 | if (error) | |
547 | return error; | 548 | return error; | |
548 | 549 | |||
549 | return 0; | 550 | return 0; | |
550 | } | 551 | } | |
551 | 552 | |||
552 | static int | 553 | static int | |
553 | agten_putpalreg(struct agten_softc *sc, uint8_t idx, uint8_t r, uint8_t g, | 554 | agten_putpalreg(struct agten_softc *sc, uint8_t idx, uint8_t r, uint8_t g, | |
554 | uint8_t b) | 555 | uint8_t b) | |
555 | { | 556 | { | |
556 | 557 | |||
557 | sc->sc_cmap.cm_map[idx][0] = r; | 558 | sc->sc_cmap.cm_map[idx][0] = r; | |
558 | sc->sc_cmap.cm_map[idx][1] = g; | 559 | sc->sc_cmap.cm_map[idx][1] = g; | |
559 | sc->sc_cmap.cm_map[idx][2] = b; | 560 | sc->sc_cmap.cm_map[idx][2] = b; | |
560 | agten_write_idx(sc, IBM561_CMAP_TABLE + idx); | 561 | agten_write_idx(sc, IBM561_CMAP_TABLE + idx); | |
561 | agten_write_dac(sc, IBM561_CMD_CMAP, r); | 562 | agten_write_dac(sc, IBM561_CMD_CMAP, r); | |
562 | agten_write_dac(sc, IBM561_CMD_CMAP, g); | 563 | agten_write_dac(sc, IBM561_CMD_CMAP, g); | |
563 | agten_write_dac(sc, IBM561_CMD_CMAP, b); | 564 | agten_write_dac(sc, IBM561_CMD_CMAP, b); | |
564 | return 0; | 565 | return 0; | |
565 | } | 566 | } | |
566 | 567 | |||
567 | static void | 568 | static void | |
568 | agten_init(struct agten_softc *sc) | 569 | agten_init(struct agten_softc *sc) | |
569 | { | 570 | { | |
570 | int i, j; | 571 | int i, j; | |
571 | uint32_t src, srcw; | 572 | uint32_t src, srcw; | |
572 | volatile uint32_t junk; | 573 | volatile uint32_t junk; | |
573 | 574 | |||
574 | /* first we set up the colour map */ | 575 | /* first we set up the colour map */ | |
575 | j = 0; | 576 | j = 0; | |
576 | for (i = 0; i < 256; i++) { | 577 | for (i = 0; i < 256; i++) { | |
577 | 578 | |||
578 | agten_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1], | 579 | agten_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1], | |
579 | rasops_cmap[j + 2]); | 580 | rasops_cmap[j + 2]); | |
580 | j += 3; | 581 | j += 3; | |
581 | } | 582 | } | |
582 | 583 | |||
583 | /* then we set up a linear LUT for 24bit colour */ | 584 | /* then we set up a linear LUT for 24bit colour */ | |
584 | agten_write_idx(sc, IBM561_CMAP_TABLE + 256); | 585 | agten_write_idx(sc, IBM561_CMAP_TABLE + 256); | |
585 | for (i = 0; i < 256; i++) { | 586 | for (i = 0; i < 256; i++) { | |
586 | agten_write_dac(sc, IBM561_CMD_CMAP, i); | 587 | agten_write_dac(sc, IBM561_CMD_CMAP, i); | |
587 | agten_write_dac(sc, IBM561_CMD_CMAP, i); | 588 | agten_write_dac(sc, IBM561_CMD_CMAP, i); | |
588 | agten_write_dac(sc, IBM561_CMD_CMAP, i); | 589 | agten_write_dac(sc, IBM561_CMD_CMAP, i); | |
589 | } | 590 | } | |
590 | 591 | |||
591 | /* and the linear gamma maps */ | 592 | /* and the linear gamma maps */ | |
592 | agten_write_idx(sc, IBM561_RED_GAMMA_TABLE); | 593 | agten_write_idx(sc, IBM561_RED_GAMMA_TABLE); | |
593 | for (i = 0; i < 0x3ff; i+= 4) | 594 | for (i = 0; i < 0x3ff; i+= 4) | |
594 | agten_write_dac_10(sc, IBM561_CMD_GAMMA, i); | 595 | agten_write_dac_10(sc, IBM561_CMD_GAMMA, i); | |
595 | agten_write_idx(sc, IBM561_GREEN_GAMMA_TABLE); | 596 | agten_write_idx(sc, IBM561_GREEN_GAMMA_TABLE); | |
596 | for (i = 0; i < 0x3ff; i+= 4) | 597 | for (i = 0; i < 0x3ff; i+= 4) | |
597 | agten_write_dac_10(sc, IBM561_CMD_GAMMA, i); | 598 | agten_write_dac_10(sc, IBM561_CMD_GAMMA, i); | |
598 | agten_write_idx(sc, IBM561_BLUE_GAMMA_TABLE); | 599 | agten_write_idx(sc, IBM561_BLUE_GAMMA_TABLE); | |
599 | for (i = 0; i < 0x3ff; i+= 4) | 600 | for (i = 0; i < 0x3ff; i+= 4) | |
600 | agten_write_dac_10(sc, IBM561_CMD_GAMMA, i); | 601 | agten_write_dac_10(sc, IBM561_CMD_GAMMA, i); | |
601 | 602 | |||
602 | /* enable outputs, RGB mode */ | 603 | /* enable outputs, RGB mode */ | |
603 | agten_write_idx(sc, IBM561_CONFIG_REG3); | 604 | agten_write_idx(sc, IBM561_CONFIG_REG3); | |
604 | agten_write_dac(sc, IBM561_CMD, CR3_SERIAL_CLK_CTRL | CR3_RGB); | 605 | agten_write_dac(sc, IBM561_CMD, CR3_SERIAL_CLK_CTRL | CR3_RGB); | |
605 | 606 | |||
606 | /* MUX 4:1 basic, 8bit overlay, 8bit WIDs */ | 607 | /* MUX 4:1 basic, 8bit overlay, 8bit WIDs */ | |
607 | agten_write_idx(sc, IBM561_CONFIG_REG1); | 608 | agten_write_idx(sc, IBM561_CONFIG_REG1); | |
608 | agten_write_dac(sc, IBM561_CMD, CR1_MODE_4_1_BASIC | CR1_OVL_8BPP | | 609 | agten_write_dac(sc, IBM561_CMD, CR1_MODE_4_1_BASIC | CR1_OVL_8BPP | | |
609 | CR1_WID_8); | 610 | CR1_WID_8); | |
610 | 611 | |||
611 | /* use external clock, enable video output */ | 612 | /* use external clock, enable video output */ | |
612 | agten_write_idx(sc, IBM561_CONFIG_REG2); | 613 | agten_write_idx(sc, IBM561_CONFIG_REG2); | |
613 | agten_write_dac(sc, IBM561_CMD, CR2_ENABLE_CLC | CR2_PLL_REF_SELECT | | 614 | agten_write_dac(sc, IBM561_CMD, CR2_ENABLE_CLC | CR2_PLL_REF_SELECT | | |
614 | CR2_PIXEL_CLOCK_SELECT | CR2_ENABLE_RGB_OUTPUT); | 615 | CR2_PIXEL_CLOCK_SELECT | CR2_ENABLE_RGB_OUTPUT); | |
615 | 616 | |||
616 | /* now set up some window attributes */ | 617 | /* now set up some window attributes */ | |
617 | 618 | |||
618 | /* | 619 | /* | |
619 | * direct colour, 24 bit, transparency off, LUT from 0x100 | 620 | * direct colour, 24 bit, transparency off, LUT from 0x100 | |
620 | * we need to use direct colour and a linear LUT because for some | 621 | * we need to use direct colour and a linear LUT because for some | |
621 | * reason true color mode gives messed up colours | 622 | * reason true color mode gives messed up colours | |
622 | */ | 623 | */ | |
623 | agten_write_idx(sc, IBM561_FB_WINTYPE); | 624 | agten_write_idx(sc, IBM561_FB_WINTYPE); | |
624 | agten_write_dac_10(sc, IBM561_CMD_FB_WAT, 0x100 | FB_PIXEL_24BIT | | 625 | agten_write_dac_10(sc, IBM561_CMD_FB_WAT, 0x100 | FB_PIXEL_24BIT | | |
625 | FB_MODE_DIRECT); | 626 | FB_MODE_DIRECT); | |
626 | 627 | |||
627 | /* use gamma LUTs, no crosshair, 0 is transparent */ | 628 | /* use gamma LUTs, no crosshair, 0 is transparent */ | |
628 | agten_write_idx(sc, IBM561_AUXFB_WINTYPE); | 629 | agten_write_idx(sc, IBM561_AUXFB_WINTYPE); | |
629 | agten_write_dac(sc, IBM561_CMD_FB_WAT, 0x0); | 630 | agten_write_dac(sc, IBM561_CMD_FB_WAT, 0x0); | |
630 | 631 | |||
631 | /* overlay is 8 bit, opaque */ | 632 | /* overlay is 8 bit, opaque */ | |
632 | agten_write_idx(sc, IBM561_OL_WINTYPE); | 633 | agten_write_idx(sc, IBM561_OL_WINTYPE); | |
633 | agten_write_dac_10(sc, IBM561_CMD_FB_WAT, 0x00); | 634 | agten_write_dac_10(sc, IBM561_CMD_FB_WAT, 0x00); | |
634 | 635 | |||
635 | /* now we fill the WID fb with zeroes */ | 636 | /* now we fill the WID fb with zeroes */ | |
636 | src = 0; | 637 | src = 0; | |
637 | srcw = sc->sc_width << 16 | sc->sc_height; | 638 | srcw = sc->sc_width << 16 | sc->sc_height; | |
638 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, FOREGROUND_COLOR, | 639 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, FOREGROUND_COLOR, | |
639 | 0x0); | 640 | 0x0); | |
640 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, BACKGROUND_COLOR, | 641 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, BACKGROUND_COLOR, | |
641 | 0x0); | 642 | 0x0); | |
642 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, RASTER_OP, ROP_PAT); | 643 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, RASTER_OP, ROP_PAT); | |
643 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, COORD_INDEX, 0); | 644 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, COORD_INDEX, 0); | |
644 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, RECT_RTW_XY, src); | 645 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, RECT_RTW_XY, src); | |
645 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, RECT_RTW_XY, srcw); | 646 | bus_space_write_4(sc->sc_bustag, sc->sc_p9100_regh, RECT_RTW_XY, srcw); | |
646 | junk = bus_space_read_4(sc->sc_bustag, sc->sc_p9100_regh, COMMAND_QUAD); | 647 | junk = bus_space_read_4(sc->sc_bustag, sc->sc_p9100_regh, COMMAND_QUAD); | |
647 | 648 | |||
648 | /* initialize the cursor registers */ | 649 | /* initialize the cursor registers */ | |
649 | 650 | |||
650 | /* initialize the Imagine 128 */ | 651 | /* initialize the Imagine 128 */ | |
651 | i128_init(sc->sc_bustag, sc->sc_i128_regh, sc->sc_stride, 8); | 652 | i128_init(sc->sc_bustag, sc->sc_i128_regh, sc->sc_stride, 8); | |
652 | } | 653 | } | |
653 | 654 | |||
654 | static void | 655 | static void | |
655 | agten_gfx(struct agten_softc *sc) | 656 | agten_gfx(struct agten_softc *sc) | |
656 | { | 657 | { | |
657 | /* enable overlay transparency on colour 0x00 */ | 658 | /* enable overlay transparency on colour 0x00 */ | |
658 | agten_write_idx(sc, IBM561_OL_WINTYPE); | 659 | agten_write_idx(sc, IBM561_OL_WINTYPE); | |
659 | agten_write_dac_10(sc, IBM561_CMD_FB_WAT, OL_MODE_TRANSP_ENABLE); | 660 | agten_write_dac_10(sc, IBM561_CMD_FB_WAT, OL_MODE_TRANSP_ENABLE); | |
660 | 661 | |||
661 | /* then blit the overlay full of 0x00 */ | 662 | /* then blit the overlay full of 0x00 */ | |
662 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, 0, 0, sc->sc_width, | 663 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, 0, 0, sc->sc_width, | |
663 | sc->sc_height, 0); | 664 | sc->sc_height, 0); | |
664 | 665 | |||
665 | /* ... so we can see the 24bit framebuffer */ | 666 | /* ... so we can see the 24bit framebuffer */ | |
666 | } | 667 | } | |
667 | 668 | |||
668 | static void | 669 | static void | |
669 | agten_set_video(struct agten_softc *sc, int flag) | 670 | agten_set_video(struct agten_softc *sc, int flag) | |
670 | { | 671 | { | |
671 | uint8_t reg = | 672 | uint8_t reg = | |
672 | CR2_ENABLE_CLC | CR2_PLL_REF_SELECT | CR2_PIXEL_CLOCK_SELECT; | 673 | CR2_ENABLE_CLC | CR2_PLL_REF_SELECT | CR2_PIXEL_CLOCK_SELECT; | |
673 | 674 | |||
674 | if (flag == sc->sc_video) | 675 | if (flag == sc->sc_video) | |
675 | return; | 676 | return; | |
676 | 677 | |||
677 | agten_write_idx(sc, IBM561_CONFIG_REG2); | 678 | agten_write_idx(sc, IBM561_CONFIG_REG2); | |
678 | agten_write_dac(sc, IBM561_CMD, flag ? reg | CR2_ENABLE_RGB_OUTPUT : | 679 | agten_write_dac(sc, IBM561_CMD, flag ? reg | CR2_ENABLE_RGB_OUTPUT : | |
679 | reg); | 680 | reg); | |
680 | 681 | |||
681 | sc->sc_video = flag; | 682 | sc->sc_video = flag; | |
682 | } | 683 | } | |
683 | 684 | |||
684 | static int | 685 | static int | |
685 | agten_get_video(struct agten_softc *sc) | 686 | agten_get_video(struct agten_softc *sc) | |
686 | { | 687 | { | |
687 | 688 | |||
688 | return sc->sc_video; | 689 | return sc->sc_video; | |
689 | } | 690 | } | |
690 | 691 | |||
691 | static void | 692 | static void | |
692 | agten_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) | 693 | agten_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) | |
693 | { | 694 | { | |
694 | struct rasops_info *ri = cookie; | 695 | struct rasops_info *ri = cookie; | |
695 | struct vcons_screen *scr = ri->ri_hw; | 696 | struct vcons_screen *scr = ri->ri_hw; | |
696 | struct agten_softc *sc = scr->scr_cookie; | 697 | struct agten_softc *sc = scr->scr_cookie; | |
697 | int32_t xs, xd, y, width, height; | 698 | int32_t xs, xd, y, width, height; | |
698 | 699 | |||
699 | xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; | 700 | xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; | |
700 | xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; | 701 | xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; | |
701 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 702 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
702 | width = ri->ri_font->fontwidth * ncols; | 703 | width = ri->ri_font->fontwidth * ncols; | |
703 | height = ri->ri_font->fontheight; | 704 | height = ri->ri_font->fontheight; | |
704 | i128_bitblt(sc->sc_bustag, sc->sc_i128_regh, xs, y, xd, y, width, | 705 | i128_bitblt(sc->sc_bustag, sc->sc_i128_regh, xs, y, xd, y, width, | |
705 | height, CR_COPY); | 706 | height, CR_COPY); | |
706 | } | 707 | } | |
707 | 708 | |||
708 | static void | 709 | static void | |
709 | agten_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) | 710 | agten_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) | |
710 | { | 711 | { | |
711 | struct rasops_info *ri = cookie; | 712 | struct rasops_info *ri = cookie; | |
712 | struct vcons_screen *scr = ri->ri_hw; | 713 | struct vcons_screen *scr = ri->ri_hw; | |
713 | struct agten_softc *sc = scr->scr_cookie; | 714 | struct agten_softc *sc = scr->scr_cookie; | |
714 | int32_t x, y, width, height, bg; | 715 | int32_t x, y, width, height, bg; | |
715 | 716 | |||
716 | x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; | 717 | x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; | |
717 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 718 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
718 | width = ri->ri_font->fontwidth * ncols; | 719 | width = ri->ri_font->fontwidth * ncols; | |
719 | height = ri->ri_font->fontheight; | 720 | height = ri->ri_font->fontheight; | |
720 | bg = (uint32_t)ri->ri_devcmap[(fillattr >> 16) & 0xff]; | 721 | bg = (uint32_t)ri->ri_devcmap[(fillattr >> 16) & 0xff]; | |
721 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x, y, width, height, bg); | 722 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x, y, width, height, bg); | |
722 | } | 723 | } | |
723 | 724 | |||
724 | static void | 725 | static void | |
725 | agten_copyrows(void *cookie, int srcrow, int dstrow, int nrows) | 726 | agten_copyrows(void *cookie, int srcrow, int dstrow, int nrows) | |
726 | { | 727 | { | |
727 | struct rasops_info *ri = cookie; | 728 | struct rasops_info *ri = cookie; | |
728 | struct vcons_screen *scr = ri->ri_hw; | 729 | struct vcons_screen *scr = ri->ri_hw; | |
729 | struct agten_softc *sc = scr->scr_cookie; | 730 | struct agten_softc *sc = scr->scr_cookie; | |
730 | int32_t x, ys, yd, width, height; | 731 | int32_t x, ys, yd, width, height; | |
731 | 732 | |||
732 | x = ri->ri_xorigin; | 733 | x = ri->ri_xorigin; | |
733 | ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; | 734 | ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; | |
734 | yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; | 735 | yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; | |
735 | width = ri->ri_emuwidth; | 736 | width = ri->ri_emuwidth; | |
736 | height = ri->ri_font->fontheight * nrows; | 737 | height = ri->ri_font->fontheight * nrows; | |
737 | i128_bitblt(sc->sc_bustag, sc->sc_i128_regh, x, ys, x, yd, width, | 738 | i128_bitblt(sc->sc_bustag, sc->sc_i128_regh, x, ys, x, yd, width, | |
738 | height, CR_COPY); | 739 | height, CR_COPY); | |
739 | } | 740 | } | |
740 | 741 | |||
741 | static void | 742 | static void | |
742 | agten_eraserows(void *cookie, int row, int nrows, long fillattr) | 743 | agten_eraserows(void *cookie, int row, int nrows, long fillattr) | |
743 | { | 744 | { | |
744 | struct rasops_info *ri = cookie; | 745 | struct rasops_info *ri = cookie; | |
745 | struct vcons_screen *scr = ri->ri_hw; | 746 | struct vcons_screen *scr = ri->ri_hw; | |
746 | struct agten_softc *sc = scr->scr_cookie; | 747 | struct agten_softc *sc = scr->scr_cookie; | |
747 | int32_t x, y, width, height, bg; | 748 | int32_t x, y, width, height, bg; | |
748 | 749 | |||
749 | if ((row == 0) && (nrows == ri->ri_rows)) { | 750 | if ((row == 0) && (nrows == ri->ri_rows)) { | |
750 | x = y = 0; | 751 | x = y = 0; | |
751 | width = ri->ri_width; | 752 | width = ri->ri_width; | |
752 | height = ri->ri_height; | 753 | height = ri->ri_height; | |
753 | } else { | 754 | } else { | |
754 | x = ri->ri_xorigin; | 755 | x = ri->ri_xorigin; | |
755 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 756 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
756 | width = ri->ri_emuwidth; | 757 | width = ri->ri_emuwidth; | |
757 | height = ri->ri_font->fontheight * nrows; | 758 | height = ri->ri_font->fontheight * nrows; | |
758 | } | 759 | } | |
759 | bg = (uint32_t)ri->ri_devcmap[(fillattr >> 16) & 0xff]; | 760 | bg = (uint32_t)ri->ri_devcmap[(fillattr >> 16) & 0xff]; | |
760 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x, y, width, height, bg); | 761 | i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x, y, width, height, bg); | |
761 | } | 762 | } | |
762 | 763 | |||
763 | static void | 764 | static void | |
764 | agten_move_cursor(struct agten_softc *sc, int x, int y) | 765 | agten_move_cursor(struct agten_softc *sc, int x, int y) | |
765 | { | 766 | { | |
766 | 767 | |||
767 | sc->sc_cursor_x = x; | 768 | sc->sc_cursor_x = x; | |
768 | sc->sc_cursor_y = y; | 769 | sc->sc_cursor_y = y; | |
769 | agten_write_idx(sc, IBM561_CURSOR_X_REG); | 770 | agten_write_idx(sc, IBM561_CURSOR_X_REG); | |
770 | agten_write_dac(sc, IBM561_CMD, x & 0xff); | 771 | agten_write_dac(sc, IBM561_CMD, x & 0xff); | |
771 | agten_write_dac(sc, IBM561_CMD, (x >> 8) & 0xff); | 772 | agten_write_dac(sc, IBM561_CMD, (x >> 8) & 0xff); | |
772 | agten_write_dac(sc, IBM561_CMD, y & 0xff); | 773 | agten_write_dac(sc, IBM561_CMD, y & 0xff); | |
773 | agten_write_dac(sc, IBM561_CMD, (y >> 8) & 0xff); | 774 | agten_write_dac(sc, IBM561_CMD, (y >> 8) & 0xff); | |
774 | } | 775 | } | |
775 | 776 | |||
776 | static int | 777 | static int | |
777 | agten_do_cursor(struct agten_softc *sc, struct wsdisplay_cursor *cur) | 778 | agten_do_cursor(struct agten_softc *sc, struct wsdisplay_cursor *cur) | |
778 | { | 779 | { | |
779 | if (cur->which & WSDISPLAY_CURSOR_DOCUR) { | 780 | if (cur->which & WSDISPLAY_CURSOR_DOCUR) { | |
780 | 781 | |||
781 | agten_write_idx(sc, IBM561_CURS_CNTL_REG); | 782 | agten_write_idx(sc, IBM561_CURS_CNTL_REG); | |
782 | agten_write_dac(sc, IBM561_CMD, cur->enable ? | 783 | agten_write_dac(sc, IBM561_CMD, cur->enable ? | |
783 | CURS_ENABLE : 0); | 784 | CURS_ENABLE : 0); | |
784 | } | 785 | } | |
785 | if (cur->which & WSDISPLAY_CURSOR_DOHOT) { | 786 | if (cur->which & WSDISPLAY_CURSOR_DOHOT) { | |
786 | 787 | |||
787 | agten_write_idx(sc, IBM561_HOTSPOT_X_REG); | 788 | agten_write_idx(sc, IBM561_HOTSPOT_X_REG); | |
788 | agten_write_dac(sc, IBM561_CMD, cur->hot.x); | 789 | agten_write_dac(sc, IBM561_CMD, cur->hot.x); | |
789 | agten_write_dac(sc, IBM561_CMD, cur->hot.y); | 790 | agten_write_dac(sc, IBM561_CMD, cur->hot.y); | |
790 | } | 791 | } | |
791 | if (cur->which & WSDISPLAY_CURSOR_DOPOS) { | 792 | if (cur->which & WSDISPLAY_CURSOR_DOPOS) { | |
792 | 793 | |||
793 | agten_move_cursor(sc, cur->pos.x, cur->pos.y); | 794 | agten_move_cursor(sc, cur->pos.x, cur->pos.y); | |
794 | } | 795 | } | |
795 | if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { | 796 | if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { | |
796 | int i; | 797 | int i; | |
797 | 798 | |||
798 | agten_write_idx(sc, IBM561_CURSOR_LUT + cur->cmap.index + 2); | 799 | agten_write_idx(sc, IBM561_CURSOR_LUT + cur->cmap.index + 2); | |
799 | for (i = 0; i < cur->cmap.count; i++) { | 800 | for (i = 0; i < cur->cmap.count; i++) { | |
800 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.red[i]); | 801 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.red[i]); | |
801 | agten_write_dac(sc, IBM561_CMD_CMAP, | 802 | agten_write_dac(sc, IBM561_CMD_CMAP, | |
802 | cur->cmap.green[i]); | 803 | cur->cmap.green[i]); | |
803 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.blue[i]); | 804 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.blue[i]); | |
804 | } | 805 | } | |
805 | } | 806 | } | |
806 | if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { | 807 | if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { | |
807 | int i; | 808 | int i; | |
808 | uint16_t tmp; | 809 | uint16_t tmp; | |
809 | 810 | |||
810 | agten_write_idx(sc, IBM561_CURSOR_BITMAP); | 811 | agten_write_idx(sc, IBM561_CURSOR_BITMAP); | |
811 | for (i = 0; i < 512; i++) { | 812 | for (i = 0; i < 512; i++) { | |
812 | tmp = util_interleave(cur->mask[i], cur->image[i]); | 813 | tmp = util_interleave(cur->mask[i], cur->image[i]); | |
813 | agten_write_dac(sc, IBM561_CMD, (tmp >> 8) & 0xff); | 814 | agten_write_dac(sc, IBM561_CMD, (tmp >> 8) & 0xff); | |
814 | agten_write_dac(sc, IBM561_CMD, tmp & 0xff); | 815 | agten_write_dac(sc, IBM561_CMD, tmp & 0xff); | |
815 | } | 816 | } | |
816 | } | 817 | } | |
817 | return 0; | 818 | return 0; | |
818 | } | 819 | } | |
819 | 820 | |||
820 | static int | 821 | static int | |
821 | agten_do_sun_cursor(struct agten_softc *sc, struct fbcursor *cur) | 822 | agten_do_sun_cursor(struct agten_softc *sc, struct fbcursor *cur) | |
822 | { | 823 | { | |
823 | if (cur->set & FB_CUR_SETCUR) { | 824 | if (cur->set & FB_CUR_SETCUR) { | |
824 | 825 | |||
825 | agten_write_idx(sc, IBM561_CURS_CNTL_REG); | 826 | agten_write_idx(sc, IBM561_CURS_CNTL_REG); | |
826 | agten_write_dac(sc, IBM561_CMD, cur->enable ? | 827 | agten_write_dac(sc, IBM561_CMD, cur->enable ? | |
827 | CURS_ENABLE : 0); | 828 | CURS_ENABLE : 0); | |
828 | } | 829 | } | |
829 | if (cur->set & FB_CUR_SETHOT) { | 830 | if (cur->set & FB_CUR_SETHOT) { | |
830 | 831 | |||
831 | agten_write_idx(sc, IBM561_HOTSPOT_X_REG); | 832 | agten_write_idx(sc, IBM561_HOTSPOT_X_REG); | |
832 | agten_write_dac(sc, IBM561_CMD, cur->hot.x); | 833 | agten_write_dac(sc, IBM561_CMD, cur->hot.x); | |
833 | agten_write_dac(sc, IBM561_CMD, cur->hot.y); | 834 | agten_write_dac(sc, IBM561_CMD, cur->hot.y); | |
834 | } | 835 | } | |
835 | if (cur->set & FB_CUR_SETPOS) { | 836 | if (cur->set & FB_CUR_SETPOS) { | |
836 | 837 | |||
837 | agten_move_cursor(sc, cur->pos.x, cur->pos.y); | 838 | agten_move_cursor(sc, cur->pos.x, cur->pos.y); | |
838 | } | 839 | } | |
839 | if (cur->set & FB_CUR_SETCMAP) { | 840 | if (cur->set & FB_CUR_SETCMAP) { | |
840 | int i; | 841 | int i; | |
841 | 842 | |||
842 | agten_write_idx(sc, IBM561_CURSOR_LUT + cur->cmap.index + 2); | 843 | agten_write_idx(sc, IBM561_CURSOR_LUT + cur->cmap.index + 2); | |
843 | for (i = 0; i < cur->cmap.count; i++) { | 844 | for (i = 0; i < cur->cmap.count; i++) { | |
844 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.red[i]); | 845 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.red[i]); | |
845 | agten_write_dac(sc, IBM561_CMD_CMAP, | 846 | agten_write_dac(sc, IBM561_CMD_CMAP, | |
846 | cur->cmap.green[i]); | 847 | cur->cmap.green[i]); | |
847 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.blue[i]); | 848 | agten_write_dac(sc, IBM561_CMD_CMAP, cur->cmap.blue[i]); | |
848 | } | 849 | } | |
849 | } | 850 | } | |
850 | if (cur->set & FB_CUR_SETSHAPE) { | 851 | if (cur->set & FB_CUR_SETSHAPE) { | |
851 | int i; | 852 | int i; | |
852 | uint16_t tmp; | 853 | uint16_t tmp; | |
853 | 854 | |||
854 | agten_write_idx(sc, IBM561_CURSOR_BITMAP); | 855 | agten_write_idx(sc, IBM561_CURSOR_BITMAP); | |
855 | for (i = 0; i < 512; i++) { | 856 | for (i = 0; i < 512; i++) { | |
856 | tmp = util_interleave_lin(cur->mask[i], cur->image[i]); | 857 | tmp = util_interleave_lin(cur->mask[i], cur->image[i]); | |
857 | agten_write_dac(sc, IBM561_CMD, (tmp >> 8) & 0xff); | 858 | agten_write_dac(sc, IBM561_CMD, (tmp >> 8) & 0xff); | |
858 | agten_write_dac(sc, IBM561_CMD, tmp & 0xff); | 859 | agten_write_dac(sc, IBM561_CMD, tmp & 0xff); | |
859 | } | 860 | } | |
860 | } | 861 | } | |
861 | return 0; | 862 | return 0; | |
862 | } | 863 | } | |
863 | 864 | |||
864 | uint16_t | 865 | uint16_t | |
865 | util_interleave(uint8_t b1, uint8_t b2) | 866 | util_interleave(uint8_t b1, uint8_t b2) | |
866 | { | 867 | { | |
867 | int i; | 868 | int i; | |
868 | uint16_t ret = 0; | 869 | uint16_t ret = 0; | |
869 | uint16_t mask = 0x8000; | 870 | uint16_t mask = 0x8000; | |
870 | uint8_t mask8 = 0x01; | 871 | uint8_t mask8 = 0x01; | |
871 | 872 | |||
872 | for (i = 0; i < 8; i++) { | 873 | for (i = 0; i < 8; i++) { | |
873 | if (b1 & mask8) | 874 | if (b1 & mask8) | |
874 | ret |= mask; | 875 | ret |= mask; | |
875 | mask = mask >> 1; | 876 | mask = mask >> 1; | |
876 | if (b2 & mask8) | 877 | if (b2 & mask8) | |
877 | ret |= mask; | 878 | ret |= mask; | |
878 | mask = mask >> 1; | 879 | mask = mask >> 1; | |
879 | mask8 = mask8 << 1; | 880 | mask8 = mask8 << 1; | |
880 | } | 881 | } | |
881 | return ret; | 882 | return ret; | |
882 | } | 883 | } | |
883 | 884 | |||
884 | uint16_t | 885 | uint16_t | |
885 | util_interleave_lin(uint8_t b1, uint8_t b2) | 886 | util_interleave_lin(uint8_t b1, uint8_t b2) | |
886 | { | 887 | { | |
887 | int i; | 888 | int i; | |
888 | uint16_t ret = 0; | 889 | uint16_t ret = 0; | |
889 | uint16_t mask = 0x8000; | 890 | uint16_t mask = 0x8000; | |
890 | uint8_t mask8 = 0x80; | 891 | uint8_t mask8 = 0x80; | |
891 | 892 | |||
892 | for (i = 0; i < 8; i++) { | 893 | for (i = 0; i < 8; i++) { | |
893 | if (b1 & mask8) | 894 | if (b1 & mask8) | |
894 | ret |= mask; | 895 | ret |= mask; | |
895 | mask = mask >> 1; | 896 | mask = mask >> 1; | |
896 | if (b2 & mask8) | 897 | if (b2 & mask8) | |
897 | ret |= mask; | 898 | ret |= mask; | |
898 | mask = mask >> 1; | 899 | mask = mask >> 1; | |
899 | mask8 = mask8 >> 1; | 900 | mask8 = mask8 >> 1; | |
900 | } | 901 | } | |
901 | return ret; | 902 | return ret; | |
902 | } | 903 | } | |
903 | 904 | |||
904 | /* and now the /dev/fb* stuff */ | 905 | /* and now the /dev/fb* stuff */ | |
905 | static void | 906 | static void | |
906 | agten_fb_unblank(device_t dev) | 907 | agten_fb_unblank(device_t dev) | |
907 | { | 908 | { | |
908 | struct agten_softc *sc = device_private(dev); | 909 | struct agten_softc *sc = device_private(dev); | |
909 | 910 | |||
910 | agten_init(sc); | 911 | agten_init(sc); | |
911 | agten_set_video(sc, 1); | 912 | agten_set_video(sc, 1); | |
912 | } | 913 | } | |
913 | 914 | |||
914 | static int | 915 | static int | |
915 | agten_fb_open(dev_t dev, int flags, int mode, struct lwp *l) | 916 | agten_fb_open(dev_t dev, int flags, int mode, struct lwp *l) | |
916 | { | 917 | { | |
917 | struct agten_softc *sc; | 918 | struct agten_softc *sc; | |
918 | 919 | |||
919 | sc = device_lookup_private(&agten_cd, minor(dev)); | 920 | sc = device_lookup_private(&agten_cd, minor(dev)); | |
920 | if (sc == NULL) | 921 | if (sc == NULL) | |
921 | return (ENXIO); | 922 | return (ENXIO); | |
922 | if (sc->sc_fb_is_open) | 923 | if (sc->sc_fb_is_open) | |
923 | return 0; | 924 | return 0; | |
924 | 925 | |||
925 | sc->sc_fb_is_open++; | 926 | sc->sc_fb_is_open++; | |
926 | agten_gfx(sc); | 927 | agten_gfx(sc); | |
927 | 928 | |||
928 | return (0); | 929 | return (0); | |
929 | } | 930 | } | |
930 | 931 | |||
931 | static int | 932 | static int | |
932 | agten_fb_close(dev_t dev, int flags, int mode, struct lwp *l) | 933 | agten_fb_close(dev_t dev, int flags, int mode, struct lwp *l) | |
933 | { | 934 | { | |
934 | struct agten_softc *sc; | 935 | struct agten_softc *sc; | |
935 | 936 | |||
936 | sc = device_lookup_private(&agten_cd, minor(dev)); | 937 | sc = device_lookup_private(&agten_cd, minor(dev)); | |
937 | 938 | |||
938 | sc->sc_fb_is_open--; | 939 | sc->sc_fb_is_open--; | |
939 | if (sc->sc_fb_is_open < 0) | 940 | if (sc->sc_fb_is_open < 0) | |
940 | sc->sc_fb_is_open = 0; | 941 | sc->sc_fb_is_open = 0; | |
941 | 942 | |||
942 | if (sc->sc_fb_is_open == 0) { | 943 | if (sc->sc_fb_is_open == 0) { | |
943 | agten_init(sc); | 944 | agten_init(sc); | |
944 | vcons_redraw_screen(sc->vd.active); | 945 | vcons_redraw_screen(sc->vd.active); | |
945 | } | 946 | } | |
946 | 947 | |||
947 | return (0); | 948 | return (0); | |
948 | } | 949 | } | |
949 | 950 | |||
950 | static int | 951 | static int | |
951 | agten_fb_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) | 952 | agten_fb_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) | |
952 | { | 953 | { | |
953 | struct agten_softc *sc = device_lookup_private(&agten_cd, minor(dev)); | 954 | struct agten_softc *sc = device_lookup_private(&agten_cd, minor(dev)); | |
954 | struct fbgattr *fba; | 955 | struct fbgattr *fba; | |
955 | int error; | 956 | int error; | |
956 | 957 | |||
957 | switch (cmd) { | 958 | switch (cmd) { | |
958 | 959 | |||
959 | case FBIOGTYPE: | 960 | case FBIOGTYPE: | |
960 | *(struct fbtype *)data = sc->sc_fb.fb_type; | 961 | *(struct fbtype *)data = sc->sc_fb.fb_type; | |
961 | break; | 962 | break; | |
962 | 963 | |||
963 | case FBIOGATTR: | 964 | case FBIOGATTR: | |
964 | fba = (struct fbgattr *)data; | 965 | fba = (struct fbgattr *)data; | |
965 | fba->real_type = sc->sc_fb.fb_type.fb_type; | 966 | fba->real_type = sc->sc_fb.fb_type.fb_type; | |
966 | fba->owner = 0; /* XXX ??? */ | 967 | fba->owner = 0; /* XXX ??? */ | |
967 | fba->fbtype = sc->sc_fb.fb_type; | 968 | fba->fbtype = sc->sc_fb.fb_type; | |
968 | fba->sattr.flags = 0; | 969 | fba->sattr.flags = 0; | |
969 | fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; | 970 | fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; | |
970 | fba->sattr.dev_specific[0] = -1; | 971 | fba->sattr.dev_specific[0] = -1; | |
971 | fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; | 972 | fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; | |
972 | fba->emu_types[1] = -1; | 973 | fba->emu_types[1] = -1; | |
973 | break; | 974 | break; | |
974 | 975 | |||
975 | case FBIOGETCMAP: | 976 | case FBIOGETCMAP: | |
976 | #define p ((struct fbcmap *)data) | 977 | #define p ((struct fbcmap *)data) | |
977 | return (bt_getcmap(p, &sc->sc_cmap, 256, 1)); | 978 | return (bt_getcmap(p, &sc->sc_cmap, 256, 1)); | |
978 | 979 | |||
979 | case FBIOPUTCMAP: | 980 | case FBIOPUTCMAP: | |
980 | /* copy to software map */ | 981 | /* copy to software map */ | |
981 | error = bt_putcmap(p, &sc->sc_cmap, 256, 1); | 982 | error = bt_putcmap(p, &sc->sc_cmap, 256, 1); | |
982 | if (error) | 983 | if (error) | |
983 | return (error); | 984 | return (error); | |
984 | /* now blast them into the chip */ | 985 | /* now blast them into the chip */ | |
985 | /* don't bother - we're 24bit */ | 986 | /* don't bother - we're 24bit */ | |
986 | #undef p | 987 | #undef p | |
987 | break; | 988 | break; | |
988 | 989 | |||
989 | case FBIOGVIDEO: | 990 | case FBIOGVIDEO: | |
990 | *(int *)data = agten_get_video(sc); | 991 | *(int *)data = agten_get_video(sc); | |
991 | break; | 992 | break; | |
992 | 993 | |||
993 | case FBIOSVIDEO: | 994 | case FBIOSVIDEO: | |
994 | agten_set_video(sc, *(int *)data); | 995 | agten_set_video(sc, *(int *)data); | |
995 | break; | 996 | break; | |
996 | 997 | |||
997 | /* these are for both FBIOSCURSOR and FBIOGCURSOR */ | 998 | /* these are for both FBIOSCURSOR and FBIOGCURSOR */ | |
998 | #define p ((struct fbcursor *)data) | 999 | #define p ((struct fbcursor *)data) | |
999 | #define pc (&sc->sc_cursor) | 1000 | #define pc (&sc->sc_cursor) | |
1000 | 1001 | |||
1001 | case FBIOGCURSOR: | 1002 | case FBIOGCURSOR: | |
1002 | /* does anyone use this ioctl?! */ | 1003 | /* does anyone use this ioctl?! */ | |
1003 | p->set = FB_CUR_SETALL; /* close enough, anyway */ | 1004 | p->set = FB_CUR_SETALL; /* close enough, anyway */ | |
1004 | p->enable = 1; | 1005 | p->enable = 1; | |
1005 | p->pos.x = sc->sc_cursor_x; | 1006 | p->pos.x = sc->sc_cursor_x; | |
1006 | p->pos.y = sc->sc_cursor_y; | 1007 | p->pos.y = sc->sc_cursor_y; | |
1007 | p->size.x = 64; | 1008 | p->size.x = 64; | |
1008 | p->size.y = 64; | 1009 | p->size.y = 64; | |
1009 | break; | 1010 | break; | |
1010 | 1011 | |||
1011 | case FBIOSCURSOR: | 1012 | case FBIOSCURSOR: | |
1012 | agten_do_sun_cursor(sc, p); | 1013 | agten_do_sun_cursor(sc, p); | |
1013 | break; | 1014 | break; | |
1014 | 1015 | |||
1015 | #undef p | 1016 | #undef p | |
1016 | #undef cc | 1017 | #undef cc | |
1017 | 1018 | |||
1018 | case FBIOGCURPOS: | 1019 | case FBIOGCURPOS: | |
1019 | { | 1020 | { | |
1020 | struct fbcurpos *cp = (struct fbcurpos *)data; | 1021 | struct fbcurpos *cp = (struct fbcurpos *)data; | |
1021 | cp->x = sc->sc_cursor_x; | 1022 | cp->x = sc->sc_cursor_x; | |
1022 | cp->y = sc->sc_cursor_y; | 1023 | cp->y = sc->sc_cursor_y; | |
1023 | } | 1024 | } | |
1024 | break; | 1025 | break; | |
1025 | 1026 | |||
1026 | case FBIOSCURPOS: | 1027 | case FBIOSCURPOS: | |
1027 | { | 1028 | { | |
1028 | struct fbcurpos *cp = (struct fbcurpos *)data; | 1029 | struct fbcurpos *cp = (struct fbcurpos *)data; | |
1029 | agten_move_cursor(sc, cp->x, cp->y); | 1030 | agten_move_cursor(sc, cp->x, cp->y); | |
1030 | } | 1031 | } | |
1031 | break; | 1032 | break; | |
1032 | 1033 | |||
1033 | case FBIOGCURMAX: | 1034 | case FBIOGCURMAX: | |
1034 | /* max cursor size is 64x64 */ | 1035 | /* max cursor size is 64x64 */ | |
1035 | ((struct fbcurpos *)data)->x = 64; | 1036 | ((struct fbcurpos *)data)->x = 64; | |
1036 | ((struct fbcurpos *)data)->y = 64; | 1037 | ((struct fbcurpos *)data)->y = 64; | |
1037 | break; | 1038 | break; | |
1038 | 1039 | |||
1039 | default: | 1040 | default: | |
1040 | return (ENOTTY); | 1041 | return (ENOTTY); | |
1041 | } | 1042 | } | |
1042 | return (0); | 1043 | return (0); | |
1043 | } | 1044 | } | |
1044 | 1045 | |||
1045 | static paddr_t | 1046 | static paddr_t | |
1046 | agten_fb_mmap(dev_t dev, off_t off, int prot) | 1047 | agten_fb_mmap(dev_t dev, off_t off, int prot) | |
1047 | { | 1048 | { | |
1048 | struct agten_softc *sc = device_lookup_private(&agten_cd, minor(dev)); | 1049 | struct agten_softc *sc = device_lookup_private(&agten_cd, minor(dev)); | |
1049 | 1050 | |||
1050 | /* | 1051 | /* | |
1051 | * mappings are subject to change | 1052 | * mappings are subject to change | |
1052 | * for now we put the framebuffer at offset 0 and the GLint registers | 1053 | * for now we put the framebuffer at offset 0 and the GLint registers | |
1053 | * right after that. We may want to expose more register ranges and | 1054 | * right after that. We may want to expose more register ranges and | |
1054 | * probably will want to map the 2nd framebuffer as well | 1055 | * probably will want to map the 2nd framebuffer as well | |
1055 | */ | 1056 | */ | |
1056 | 1057 | |||
1057 | if (off < 0) | 1058 | if (off < 0) | |
1058 | return EINVAL; | 1059 | return EINVAL; | |
1059 | 1060 | |||
1060 | if (off >= sc->sc_glint_fbsz + 0x10000) | 1061 | if (off >= sc->sc_glint_fbsz + 0x10000) | |
1061 | return EINVAL; | 1062 | return EINVAL; | |
1062 | 1063 | |||
1063 | if (off < sc->sc_glint_fbsz) { | 1064 | if (off < sc->sc_glint_fbsz) { | |
1064 | return (bus_space_mmap(sc->sc_bustag, | 1065 | return (bus_space_mmap(sc->sc_bustag, | |
1065 | sc->sc_glint_fb, | 1066 | sc->sc_glint_fb, | |
1066 | off, | 1067 | off, | |
1067 | prot, | 1068 | prot, | |
1068 | BUS_SPACE_MAP_LINEAR)); | 1069 | BUS_SPACE_MAP_LINEAR)); | |
1069 | } | 1070 | } | |
1070 | 1071 | |||
1071 | off -= sc->sc_glint_fbsz; | 1072 | off -= sc->sc_glint_fbsz; | |
1072 | if (off < 0x10000) { | 1073 | if (off < 0x10000) { | |
1073 | return (bus_space_mmap(sc->sc_bustag, | 1074 | return (bus_space_mmap(sc->sc_bustag, | |
1074 | sc->sc_glint_regs, | 1075 | sc->sc_glint_regs, | |
1075 | off, | 1076 | off, | |
1076 | prot, | 1077 | prot, | |
1077 | BUS_SPACE_MAP_LINEAR)); | 1078 | BUS_SPACE_MAP_LINEAR)); | |
1078 | } | 1079 | } | |
1079 | return EINVAL; | 1080 | return EINVAL; | |
1080 | } | 1081 | } |
--- src/sys/dev/sbus/cgsix_sbus.c 2009/05/12 13:20:05 1.28
+++ src/sys/dev/sbus/cgsix_sbus.c 2009/05/26 03:32:51 1.29
@@ -1,196 +1,197 @@ | @@ -1,196 +1,197 @@ | |||
1 | /* $NetBSD: cgsix_sbus.c,v 1.28 2009/05/12 13:20:05 cegger Exp $ */ | 1 | /* $NetBSD: cgsix_sbus.c,v 1.29 2009/05/26 03:32:51 macallan Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1998 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1998 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 Paul Kranenburg. | 8 | * by Paul Kranenburg. | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
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 (cgsix) driver; Sbus bus front-end. | 33 | * color display (cgsix) driver; Sbus bus front-end. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(0, "$NetBSD: cgsix_sbus.c,v 1.28 2009/05/12 13:20:05 cegger Exp $"); | 37 | __KERNEL_RCSID(0, "$NetBSD: cgsix_sbus.c,v 1.29 2009/05/26 03:32:51 macallan Exp $"); | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/systm.h> | 40 | #include <sys/systm.h> | |
41 | #include <sys/buf.h> | 41 | #include <sys/buf.h> | |
42 | #include <sys/device.h> | 42 | #include <sys/device.h> | |
43 | #include <sys/ioctl.h> | 43 | #include <sys/ioctl.h> | |
44 | #include <sys/malloc.h> | 44 | #include <sys/malloc.h> | |
45 | #include <sys/mman.h> | 45 | #include <sys/mman.h> | |
46 | #include <sys/tty.h> | 46 | #include <sys/tty.h> | |
47 | #include <sys/conf.h> | 47 | #include <sys/conf.h> | |
48 | 48 | |||
49 | #ifdef DEBUG | 49 | #ifdef DEBUG | |
50 | #include <sys/proc.h> | 50 | #include <sys/proc.h> | |
51 | #include <sys/syslog.h> | 51 | #include <sys/syslog.h> | |
52 | #endif | 52 | #endif | |
53 | 53 | |||
54 | #include <sys/bus.h> | 54 | #include <sys/bus.h> | |
55 | #include <machine/autoconf.h> | 55 | #include <machine/autoconf.h> | |
56 | 56 | |||
57 | #include <dev/sbus/sbusvar.h> | 57 | #include <dev/sbus/sbusvar.h> | |
58 | 58 | |||
59 | #include <dev/sun/fbio.h> | 59 | #include <dev/sun/fbio.h> | |
60 | #include <dev/sun/fbvar.h> | 60 | #include <dev/sun/fbvar.h> | |
61 | #include <dev/sun/btreg.h> | 61 | #include <dev/sun/btreg.h> | |
62 | #include <dev/sun/btvar.h> | 62 | #include <dev/sun/btvar.h> | |
63 | #include <dev/sun/cgsixreg.h> | 63 | #include <dev/sun/cgsixreg.h> | |
64 | #include <dev/sun/cgsixvar.h> | 64 | #include <dev/sun/cgsixvar.h> | |
65 | 65 | |||
66 | /* autoconfiguration driver */ | 66 | /* autoconfiguration driver */ | |
67 | static int cgsixmatch(device_t, cfdata_t, void *); | 67 | static int cgsixmatch(device_t, cfdata_t, void *); | |
68 | static void cgsixattach(device_t, device_t, void *); | 68 | static void cgsixattach(device_t, device_t, void *); | |
69 | 69 | |||
70 | /* Allocate an `sbusdev' in addition to the cgsix softc */ | 70 | /* Allocate an `sbusdev' in addition to the cgsix softc */ | |
71 | struct cgsix_sbus_softc { | 71 | struct cgsix_sbus_softc { | |
72 | struct cgsix_softc bss_softc; | 72 | struct cgsix_softc bss_softc; | |
73 | struct sbusdev bss_sd; | 73 | struct sbusdev bss_sd; | |
74 | }; | 74 | }; | |
75 | 75 | |||
76 | CFATTACH_DECL_NEW(cgsix_sbus, sizeof(struct cgsix_sbus_softc), | 76 | CFATTACH_DECL_NEW(cgsix_sbus, sizeof(struct cgsix_sbus_softc), | |
77 | cgsixmatch, cgsixattach, NULL, NULL); | 77 | cgsixmatch, cgsixattach, NULL, NULL); | |
78 | 78 | |||
79 | /* | 79 | /* | |
80 | * Match a cgsix. | 80 | * Match a cgsix. | |
81 | */ | 81 | */ | |
82 | int | 82 | int | |
83 | cgsixmatch(device_t parent, cfdata_t cf, void *aux) | 83 | cgsixmatch(device_t parent, cfdata_t cf, void *aux) | |
84 | { | 84 | { | |
85 | struct sbus_attach_args *sa = aux; | 85 | struct sbus_attach_args *sa = aux; | |
86 | 86 | |||
87 | return (strcmp(cf->cf_name, sa->sa_name) == 0) ? 100 : 0; | 87 | return (strcmp(cf->cf_name, sa->sa_name) == 0) ? 100 : 0; | |
88 | } | 88 | } | |
89 | 89 | |||
90 | 90 | |||
91 | /* | 91 | /* | |
92 | * Attach a cgsix. | 92 | * Attach a cgsix. | |
93 | */ | 93 | */ | |
94 | void | 94 | void | |
95 | cgsixattach(device_t parent, device_t self, void *aux) | 95 | cgsixattach(device_t parent, device_t self, void *aux) | |
96 | { | 96 | { | |
97 | struct cgsix_sbus_softc *ssc = device_private(self); | 97 | struct cgsix_sbus_softc *ssc = device_private(self); | |
98 | struct cgsix_softc *sc = &ssc->bss_softc; | 98 | struct cgsix_softc *sc = &ssc->bss_softc; | |
99 | struct sbusdev *sd = &ssc->bss_sd; | 99 | struct sbusdev *sd = &ssc->bss_sd; | |
100 | struct sbus_attach_args *sa = aux; | 100 | struct sbus_attach_args *sa = aux; | |
101 | struct fbdevice *fb = &sc->sc_fb; | 101 | struct fbdevice *fb = &sc->sc_fb; | |
102 | int node, isconsole; | 102 | int node, isconsole; | |
103 | const char *name; | 103 | const char *name; | |
104 | bus_space_handle_t bh; | 104 | bus_space_handle_t bh; | |
105 | 105 | |||
106 | /* Remember cookies for cgsix_mmap() */ | 106 | /* Remember cookies for cgsix_mmap() */ | |
107 | sc->sc_bustag = sa->sa_bustag; | 107 | sc->sc_bustag = sa->sa_bustag; | |
108 | sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); | 108 | sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); | |
109 | sc->sc_dev = self; | 109 | sc->sc_dev = self; | |
110 | 110 | |||
111 | node = sa->sa_node; | 111 | node = sa->sa_node; | |
112 | 112 | |||
113 | fb->fb_device = sc->sc_dev; | 113 | fb->fb_device = sc->sc_dev; | |
114 | fb->fb_type.fb_type = FBTYPE_SUNFAST_COLOR; | 114 | fb->fb_type.fb_type = FBTYPE_SUNFAST_COLOR; | |
115 | fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; | 115 | fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; | |
116 | fb->fb_type.fb_depth = 8; | 116 | fb->fb_type.fb_depth = 8; | |
117 | 117 | |||
118 | fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node); | 118 | fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node); | |
119 | 119 | |||
120 | /* | 120 | /* | |
121 | * Dunno what the PROM has mapped, though obviously it must have | 121 | * Dunno what the PROM has mapped, though obviously it must have | |
122 | * the video RAM mapped. Just map what we care about for ourselves | 122 | * the video RAM mapped. Just map what we care about for ourselves | |
123 | * (the FHC, THC, and Brooktree registers). | 123 | * (the FHC, THC, and Brooktree registers). | |
124 | */ | 124 | */ | |
125 | if (sbus_bus_map(sa->sa_bustag, | 125 | if (sbus_bus_map(sa->sa_bustag, | |
126 | sa->sa_slot, | 126 | sa->sa_slot, | |
127 | sa->sa_offset + CGSIX_BT_OFFSET, | 127 | sa->sa_offset + CGSIX_BT_OFFSET, | |
128 | sizeof(*sc->sc_bt), | 128 | sizeof(*sc->sc_bt), | |
129 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 129 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
130 | aprint_error_dev(self, "cannot map brooktree registers\n"); | 130 | aprint_error_dev(self, "cannot map brooktree registers\n"); | |
131 | return; | 131 | return; | |
132 | } | 132 | } | |
133 | sc->sc_bt = (struct bt_regs *)bus_space_vaddr(sa->sa_bustag, bh); | 133 | sc->sc_bt = (struct bt_regs *)bus_space_vaddr(sa->sa_bustag, bh); | |
134 | 134 | |||
135 | if (sbus_bus_map(sa->sa_bustag, | 135 | if (sbus_bus_map(sa->sa_bustag, | |
136 | sa->sa_slot, | 136 | sa->sa_slot, | |
137 | sa->sa_offset + CGSIX_FHC_OFFSET, | 137 | sa->sa_offset + CGSIX_FHC_OFFSET, | |
138 | sizeof(*sc->sc_fhc), | 138 | sizeof(*sc->sc_fhc), | |
139 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 139 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
140 | aprint_error_dev(self, "cannot map FHC registers\n"); | 140 | aprint_error_dev(self, "cannot map FHC registers\n"); | |
141 | return; | 141 | return; | |
142 | } | 142 | } | |
143 | sc->sc_fhc = (int *)bus_space_vaddr(sa->sa_bustag, bh); | 143 | sc->sc_fhc = (int *)bus_space_vaddr(sa->sa_bustag, bh); | |
144 | 144 | |||
145 | if (sbus_bus_map(sa->sa_bustag, | 145 | if (sbus_bus_map(sa->sa_bustag, | |
146 | sa->sa_slot, | 146 | sa->sa_slot, | |
147 | sa->sa_offset + CGSIX_THC_OFFSET, | 147 | sa->sa_offset + CGSIX_THC_OFFSET, | |
148 | sizeof(*sc->sc_thc), | 148 | sizeof(*sc->sc_thc), | |
149 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 149 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
150 | aprint_error_dev(self, "cannot map THC registers\n"); | 150 | aprint_error_dev(self, "cannot map THC registers\n"); | |
151 | return; | 151 | return; | |
152 | } | 152 | } | |
153 | sc->sc_thc = (struct cg6_thc *)bus_space_vaddr(sa->sa_bustag, bh); | 153 | sc->sc_thc = (struct cg6_thc *)bus_space_vaddr(sa->sa_bustag, bh); | |
154 | 154 | |||
155 | if (sbus_bus_map(sa->sa_bustag, | 155 | if (sbus_bus_map(sa->sa_bustag, | |
156 | sa->sa_slot, | 156 | sa->sa_slot, | |
157 | sa->sa_offset + CGSIX_TEC_OFFSET, | 157 | sa->sa_offset + CGSIX_TEC_OFFSET, | |
158 | sizeof(*sc->sc_tec), | 158 | sizeof(*sc->sc_tec), | |
159 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 159 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
160 | aprint_error_dev(self, "cannot map TEC registers\n"); | 160 | aprint_error_dev(self, "cannot map TEC registers\n"); | |
161 | return; | 161 | return; | |
162 | } | 162 | } | |
163 | sc->sc_tec = (struct cg6_tec_xxx *)bus_space_vaddr(sa->sa_bustag, bh); | 163 | sc->sc_tec = (struct cg6_tec_xxx *)bus_space_vaddr(sa->sa_bustag, bh); | |
164 | 164 | |||
165 | if (sbus_bus_map(sa->sa_bustag, | 165 | if (sbus_bus_map(sa->sa_bustag, | |
166 | sa->sa_slot, | 166 | sa->sa_slot, | |
167 | sa->sa_offset + CGSIX_FBC_OFFSET, | 167 | sa->sa_offset + CGSIX_FBC_OFFSET, | |
168 | sizeof(*sc->sc_fbc), | 168 | sizeof(*sc->sc_fbc), | |
169 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 169 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
170 | aprint_error_dev(self, "cannot map FBC registers\n"); | 170 | aprint_error_dev(self, "cannot map FBC registers\n"); | |
171 | return; | 171 | return; | |
172 | } | 172 | } | |
173 | sc->sc_fbc = (struct cg6_fbc *)bus_space_vaddr(sa->sa_bustag, bh); | 173 | sc->sc_fbc = (struct cg6_fbc *)bus_space_vaddr(sa->sa_bustag, bh); | |
174 | 174 | |||
175 | sbus_establish(sd, sc->sc_dev); | 175 | sbus_establish(sd, sc->sc_dev); | |
176 | name = prom_getpropstring(node, "model"); | 176 | name = prom_getpropstring(node, "model"); | |
177 | 177 | |||
178 | isconsole = fb_is_console(node); | 178 | isconsole = fb_is_console(node); | |
179 | 179 | |||
180 | /* | 180 | /* | |
181 | * we need the address of the framebuffer, no matter if we're console or | 181 | * we need the address of the framebuffer, no matter if we're console or | |
182 | * not. | 182 | * not. | |
183 | */ | 183 | */ | |
184 | sc->sc_ramsize = prom_getpropint(node, "fbmapped", 1024 * 1024); | 184 | sc->sc_ramsize = prom_getpropint(node, "fbmapped", 1024 * 1024); | |
185 | if (sbus_bus_map(sa->sa_bustag, | 185 | if (sbus_bus_map(sa->sa_bustag, | |
186 | sa->sa_slot, | 186 | sa->sa_slot, | |
187 | sa->sa_offset + CGSIX_RAM_OFFSET, | 187 | sa->sa_offset + CGSIX_RAM_OFFSET, | |
188 | sc->sc_ramsize, | 188 | sc->sc_ramsize, | |
189 | BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 189 | BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, | |
190 | &bh) != 0) { | |||
190 | aprint_error_dev(self, "cannot map pixels\n"); | 191 | aprint_error_dev(self, "cannot map pixels\n"); | |
191 | return; | 192 | return; | |
192 | } | 193 | } | |
193 | sc->sc_fb.fb_pixels = (void *)bus_space_vaddr(sa->sa_bustag, bh); | 194 | sc->sc_fb.fb_pixels = (void *)bus_space_vaddr(sa->sa_bustag, bh); | |
194 | 195 | |||
195 | cg6attach(sc, name, isconsole); | 196 | cg6attach(sc, name, isconsole); | |
196 | } | 197 | } |
--- src/sys/dev/sbus/zx.c 2009/05/12 13:20:06 1.29
+++ src/sys/dev/sbus/zx.c 2009/05/26 03:32:51 1.30
@@ -1,1191 +1,1191 @@ | @@ -1,1191 +1,1191 @@ | |||
1 | /* $NetBSD: zx.c,v 1.29 2009/05/12 13:20:06 cegger Exp $ */ | 1 | /* $NetBSD: zx.c,v 1.30 2009/05/26 03:32:51 macallan Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2002 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2002 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 Andrew Doran. | 8 | * by Andrew Doran. | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
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 | * Driver for the Sun ZX display adapter. This would be called 'leo', but | 33 | * Driver for the Sun ZX display adapter. This would be called 'leo', but | |
34 | * NetBSD/amiga already has a driver by that name. The XFree86 and Linux | 34 | * NetBSD/amiga already has a driver by that name. The XFree86 and Linux | |
35 | * drivers were used as "living documentation" when writing this; thanks | 35 | * drivers were used as "living documentation" when writing this; thanks | |
36 | * to the authors. | 36 | * to the authors. | |
37 | * | 37 | * | |
38 | * Issues (which can be solved with wscons, happily enough): | 38 | * Issues (which can be solved with wscons, happily enough): | |
39 | * | 39 | * | |
40 | * o There is lots of unnecessary mucking about rasops in here, primarily | 40 | * o There is lots of unnecessary mucking about rasops in here, primarily | |
41 | * to appease the sparc fb code. | 41 | * to appease the sparc fb code. | |
42 | * | 42 | * | |
43 | * o RASTERCONSOLE is required. X needs the board set up correctly, and | 43 | * o RASTERCONSOLE is required. X needs the board set up correctly, and | |
44 | * that's difficult to reconcile with using the PROM for output. | 44 | * that's difficult to reconcile with using the PROM for output. | |
45 | */ | 45 | */ | |
46 | 46 | |||
47 | #include <sys/cdefs.h> | 47 | #include <sys/cdefs.h> | |
48 | __KERNEL_RCSID(0, "$NetBSD: zx.c,v 1.29 2009/05/12 13:20:06 cegger Exp $"); | 48 | __KERNEL_RCSID(0, "$NetBSD: zx.c,v 1.30 2009/05/26 03:32:51 macallan Exp $"); | |
49 | 49 | |||
50 | #include <sys/param.h> | 50 | #include <sys/param.h> | |
51 | #include <sys/systm.h> | 51 | #include <sys/systm.h> | |
52 | #include <sys/device.h> | 52 | #include <sys/device.h> | |
53 | #include <sys/ioctl.h> | 53 | #include <sys/ioctl.h> | |
54 | #include <sys/malloc.h> | 54 | #include <sys/malloc.h> | |
55 | #include <sys/mman.h> | 55 | #include <sys/mman.h> | |
56 | #include <sys/tty.h> | 56 | #include <sys/tty.h> | |
57 | #include <sys/conf.h> | 57 | #include <sys/conf.h> | |
58 | #include <sys/syslog.h> | 58 | #include <sys/syslog.h> | |
59 | #include <sys/buf.h> | 59 | #include <sys/buf.h> | |
60 | 60 | |||
61 | #include <sys/bus.h> | 61 | #include <sys/bus.h> | |
62 | #include <machine/autoconf.h> | 62 | #include <machine/autoconf.h> | |
63 | 63 | |||
64 | #include <uvm/uvm_extern.h> | 64 | #include <uvm/uvm_extern.h> | |
65 | 65 | |||
66 | #include <dev/sun/fbio.h> | 66 | #include <dev/sun/fbio.h> | |
67 | #include <dev/sun/fbvar.h> | 67 | #include <dev/sun/fbvar.h> | |
68 | 68 | |||
69 | #include "wsdisplay.h" | 69 | #include "wsdisplay.h" | |
70 | #if NWSDISPLAY > 0 | 70 | #if NWSDISPLAY > 0 | |
71 | #include <dev/wscons/wsconsio.h> | 71 | #include <dev/wscons/wsconsio.h> | |
72 | #include <dev/wsfont/wsfont.h> | 72 | #include <dev/wsfont/wsfont.h> | |
73 | #include <dev/rasops/rasops.h> | 73 | #include <dev/rasops/rasops.h> | |
74 | #include <dev/wscons/wsdisplay_vconsvar.h> | 74 | #include <dev/wscons/wsdisplay_vconsvar.h> | |
75 | 75 | |||
76 | #include "opt_wsemul.h" | 76 | #include "opt_wsemul.h" | |
77 | #endif | 77 | #endif | |
78 | 78 | |||
79 | #include <dev/sbus/zxreg.h> | 79 | #include <dev/sbus/zxreg.h> | |
80 | #include <dev/sbus/zxvar.h> | 80 | #include <dev/sbus/zxvar.h> | |
81 | #include <dev/sbus/sbusvar.h> | 81 | #include <dev/sbus/sbusvar.h> | |
82 | 82 | |||
83 | #include <dev/wscons/wsconsio.h> | 83 | #include <dev/wscons/wsconsio.h> | |
84 | 84 | |||
85 | #if (NWSDISPLAY == 0) && !defined(RASTERCONSOLE) | 85 | #if (NWSDISPLAY == 0) && !defined(RASTERCONSOLE) | |
86 | #error Sorry, this driver needs WSCONS or RASTERCONSOLE | 86 | #error Sorry, this driver needs WSCONS or RASTERCONSOLE | |
87 | #endif | 87 | #endif | |
88 | 88 | |||
89 | #if (NWSDISPLAY > 0) && defined(RASTERCONSOLE) | 89 | #if (NWSDISPLAY > 0) && defined(RASTERCONSOLE) | |
90 | #error Sorry, RASTERCONSOLE and WSCONS are mutually exclusive | 90 | #error Sorry, RASTERCONSOLE and WSCONS are mutually exclusive | |
91 | #endif | 91 | #endif | |
92 | 92 | |||
93 | #define ZX_STD_ROP (ZX_ROP_NEW | ZX_ATTR_WE_ENABLE | \ | 93 | #define ZX_STD_ROP (ZX_ROP_NEW | ZX_ATTR_WE_ENABLE | \ | |
94 | ZX_ATTR_OE_ENABLE | ZX_ATTR_FORCE_WID) | 94 | ZX_ATTR_OE_ENABLE | ZX_ATTR_FORCE_WID) | |
95 | 95 | |||
96 | static void zx_attach(device_t, device_t, void *); | 96 | static void zx_attach(device_t, device_t, void *); | |
97 | static int zx_match(device_t, cfdata_t, void *); | 97 | static int zx_match(device_t, cfdata_t, void *); | |
98 | 98 | |||
99 | static void zx_blank(device_t); | 99 | static void zx_blank(device_t); | |
100 | static int zx_cmap_put(struct zx_softc *); | 100 | static int zx_cmap_put(struct zx_softc *); | |
101 | static void zx_copyrect(struct zx_softc *, int, int, int, int, int, int); | 101 | static void zx_copyrect(struct zx_softc *, int, int, int, int, int, int); | |
102 | static int zx_cross_loadwid(struct zx_softc *, u_int, u_int, u_int); | 102 | static int zx_cross_loadwid(struct zx_softc *, u_int, u_int, u_int); | |
103 | static int zx_cross_wait(struct zx_softc *); | 103 | static int zx_cross_wait(struct zx_softc *); | |
104 | static void zx_fillrect(struct zx_softc *, int, int, int, int, uint32_t, int); | 104 | static void zx_fillrect(struct zx_softc *, int, int, int, int, uint32_t, int); | |
105 | static int zx_intr(void *); | 105 | static int zx_intr(void *); | |
106 | static void zx_reset(struct zx_softc *); | 106 | static void zx_reset(struct zx_softc *); | |
107 | static void zx_unblank(device_t); | 107 | static void zx_unblank(device_t); | |
108 | 108 | |||
109 | static void zx_cursor_blank(struct zx_softc *); | 109 | static void zx_cursor_blank(struct zx_softc *); | |
110 | static void zx_cursor_color(struct zx_softc *); | 110 | static void zx_cursor_color(struct zx_softc *); | |
111 | static void zx_cursor_move(struct zx_softc *); | 111 | static void zx_cursor_move(struct zx_softc *); | |
112 | static void zx_cursor_set(struct zx_softc *); | 112 | static void zx_cursor_set(struct zx_softc *); | |
113 | static void zx_cursor_unblank(struct zx_softc *); | 113 | static void zx_cursor_unblank(struct zx_softc *); | |
114 | 114 | |||
115 | static void zx_copycols(void *, int, int, int, int); | 115 | static void zx_copycols(void *, int, int, int, int); | |
116 | static void zx_copyrows(void *, int, int, int); | 116 | static void zx_copyrows(void *, int, int, int); | |
117 | static void zx_do_cursor(void *, int, int, int); | 117 | static void zx_do_cursor(void *, int, int, int); | |
118 | static void zx_erasecols(void *, int, int, int, long); | 118 | static void zx_erasecols(void *, int, int, int, long); | |
119 | static void zx_eraserows(void *, int, int, long); | 119 | static void zx_eraserows(void *, int, int, long); | |
120 | static void zx_putchar(void *, int, int, u_int, long); | 120 | static void zx_putchar(void *, int, int, u_int, long); | |
121 | 121 | |||
122 | struct zx_mmo { | 122 | struct zx_mmo { | |
123 | off_t mo_va; | 123 | off_t mo_va; | |
124 | off_t mo_pa; | 124 | off_t mo_pa; | |
125 | off_t mo_size; | 125 | off_t mo_size; | |
126 | } static const zx_mmo[] = { | 126 | } static const zx_mmo[] = { | |
127 | { ZX_FB0_VOFF, ZX_OFF_SS0, 0x00800000 }, | 127 | { ZX_FB0_VOFF, ZX_OFF_SS0, 0x00800000 }, | |
128 | { ZX_LC0_VOFF, ZX_OFF_LC_SS0_USR, 0x00001000 }, | 128 | { ZX_LC0_VOFF, ZX_OFF_LC_SS0_USR, 0x00001000 }, | |
129 | { ZX_LD0_VOFF, ZX_OFF_LD_SS0, 0x00001000 }, | 129 | { ZX_LD0_VOFF, ZX_OFF_LD_SS0, 0x00001000 }, | |
130 | { ZX_LX0_CURSOR_VOFF, ZX_OFF_LX_CURSOR, 0x00001000 }, | 130 | { ZX_LX0_CURSOR_VOFF, ZX_OFF_LX_CURSOR, 0x00001000 }, | |
131 | { ZX_FB1_VOFF, ZX_OFF_SS1, 0x00800000 }, | 131 | { ZX_FB1_VOFF, ZX_OFF_SS1, 0x00800000 }, | |
132 | { ZX_LC1_VOFF, ZX_OFF_LC_SS1_USR, 0x00001000 }, | 132 | { ZX_LC1_VOFF, ZX_OFF_LC_SS1_USR, 0x00001000 }, | |
133 | { ZX_LD1_VOFF, ZX_OFF_LD_SS1, 0x00001000 }, | 133 | { ZX_LD1_VOFF, ZX_OFF_LD_SS1, 0x00001000 }, | |
134 | { ZX_LX_KRN_VOFF, ZX_OFF_LX_CROSS, 0x00001000 }, | 134 | { ZX_LX_KRN_VOFF, ZX_OFF_LX_CROSS, 0x00001000 }, | |
135 | { ZX_LC0_KRN_VOFF, ZX_OFF_LC_SS0_KRN, 0x00001000 }, | 135 | { ZX_LC0_KRN_VOFF, ZX_OFF_LC_SS0_KRN, 0x00001000 }, | |
136 | { ZX_LC1_KRN_VOFF, ZX_OFF_LC_SS1_KRN, 0x00001000 }, | 136 | { ZX_LC1_KRN_VOFF, ZX_OFF_LC_SS1_KRN, 0x00001000 }, | |
137 | { ZX_LD_GBL_VOFF, ZX_OFF_LD_GBL, 0x00001000 }, | 137 | { ZX_LD_GBL_VOFF, ZX_OFF_LD_GBL, 0x00001000 }, | |
138 | }; | 138 | }; | |
139 | 139 | |||
140 | CFATTACH_DECL_NEW(zx, sizeof(struct zx_softc), | 140 | CFATTACH_DECL_NEW(zx, sizeof(struct zx_softc), | |
141 | zx_match, zx_attach, NULL, NULL); | 141 | zx_match, zx_attach, NULL, NULL); | |
142 | 142 | |||
143 | extern struct cfdriver zx_cd; | 143 | extern struct cfdriver zx_cd; | |
144 | 144 | |||
145 | static dev_type_open(zxopen); | 145 | static dev_type_open(zxopen); | |
146 | static dev_type_close(zxclose); | 146 | static dev_type_close(zxclose); | |
147 | static dev_type_ioctl(zxioctl); | 147 | static dev_type_ioctl(zxioctl); | |
148 | static dev_type_mmap(zxmmap); | 148 | static dev_type_mmap(zxmmap); | |
149 | 149 | |||
150 | static struct fbdriver zx_fbdriver = { | 150 | static struct fbdriver zx_fbdriver = { | |
151 | zx_unblank, zxopen, zxclose, zxioctl, nopoll, zxmmap | 151 | zx_unblank, zxopen, zxclose, zxioctl, nopoll, zxmmap | |
152 | }; | 152 | }; | |
153 | 153 | |||
154 | #if NWSDISPLAY > 0 | 154 | #if NWSDISPLAY > 0 | |
155 | struct wsscreen_descr zx_defaultscreen = { | 155 | struct wsscreen_descr zx_defaultscreen = { | |
156 | "std", | 156 | "std", | |
157 | 0, 0, /* will be filled in -- XXX shouldn't, it's global */ | 157 | 0, 0, /* will be filled in -- XXX shouldn't, it's global */ | |
158 | /* doesn't matter - you can't really have more than one leo */ | 158 | /* doesn't matter - you can't really have more than one leo */ | |
159 | NULL, /* textops */ | 159 | NULL, /* textops */ | |
160 | 8, 16, /* font width/height */ | 160 | 8, 16, /* font width/height */ | |
161 | WSSCREEN_WSCOLORS, /* capabilities */ | 161 | WSSCREEN_WSCOLORS, /* capabilities */ | |
162 | NULL /* modecookie */ | 162 | NULL /* modecookie */ | |
163 | }; | 163 | }; | |
164 | 164 | |||
165 | static int zx_ioctl(void *, void *, u_long, void *, int, struct lwp *); | 165 | static int zx_ioctl(void *, void *, u_long, void *, int, struct lwp *); | |
166 | static paddr_t zx_mmap(void *, void *, off_t, int); | 166 | static paddr_t zx_mmap(void *, void *, off_t, int); | |
167 | static void zx_init_screen(void *, struct vcons_screen *, int, long *); | 167 | static void zx_init_screen(void *, struct vcons_screen *, int, long *); | |
168 | 168 | |||
169 | static int zx_putcmap(struct zx_softc *, struct wsdisplay_cmap *); | 169 | static int zx_putcmap(struct zx_softc *, struct wsdisplay_cmap *); | |
170 | static int zx_getcmap(struct zx_softc *, struct wsdisplay_cmap *); | 170 | static int zx_getcmap(struct zx_softc *, struct wsdisplay_cmap *); | |
171 | 171 | |||
172 | struct wsdisplay_accessops zx_accessops = { | 172 | struct wsdisplay_accessops zx_accessops = { | |
173 | zx_ioctl, | 173 | zx_ioctl, | |
174 | zx_mmap, | 174 | zx_mmap, | |
175 | NULL, /* alloc_screen */ | 175 | NULL, /* alloc_screen */ | |
176 | NULL, /* free_screen */ | 176 | NULL, /* free_screen */ | |
177 | NULL, /* show_screen */ | 177 | NULL, /* show_screen */ | |
178 | NULL, /* load_font */ | 178 | NULL, /* load_font */ | |
179 | NULL, /* pollc */ | 179 | NULL, /* pollc */ | |
180 | NULL /* scroll */ | 180 | NULL /* scroll */ | |
181 | }; | 181 | }; | |
182 | 182 | |||
183 | const struct wsscreen_descr *_zx_scrlist[] = { | 183 | const struct wsscreen_descr *_zx_scrlist[] = { | |
184 | &zx_defaultscreen | 184 | &zx_defaultscreen | |
185 | }; | 185 | }; | |
186 | 186 | |||
187 | struct wsscreen_list zx_screenlist = { | 187 | struct wsscreen_list zx_screenlist = { | |
188 | sizeof(_zx_scrlist) / sizeof(struct wsscreen_descr *), | 188 | sizeof(_zx_scrlist) / sizeof(struct wsscreen_descr *), | |
189 | _zx_scrlist | 189 | _zx_scrlist | |
190 | }; | 190 | }; | |
191 | 191 | |||
192 | 192 | |||
193 | extern const u_char rasops_cmap[768]; | 193 | extern const u_char rasops_cmap[768]; | |
194 | 194 | |||
195 | static struct vcons_screen zx_console_screen; | 195 | static struct vcons_screen zx_console_screen; | |
196 | #endif /* NWSDISPLAY > 0 */ | 196 | #endif /* NWSDISPLAY > 0 */ | |
197 | 197 | |||
198 | static int | 198 | static int | |
199 | zx_match(device_t parent, cfdata_t cf, void *aux) | 199 | zx_match(device_t parent, cfdata_t cf, void *aux) | |
200 | { | 200 | { | |
201 | struct sbus_attach_args *sa; | 201 | struct sbus_attach_args *sa; | |
202 | 202 | |||
203 | sa = (struct sbus_attach_args *)aux; | 203 | sa = (struct sbus_attach_args *)aux; | |
204 | 204 | |||
205 | return (strcmp(sa->sa_name, "SUNW,leo") == 0); | 205 | return (strcmp(sa->sa_name, "SUNW,leo") == 0); | |
206 | } | 206 | } | |
207 | 207 | |||
208 | static void | 208 | static void | |
209 | zx_attach(device_t parent, device_t self, void *args) | 209 | zx_attach(device_t parent, device_t self, void *args) | |
210 | { | 210 | { | |
211 | struct zx_softc *sc; | 211 | struct zx_softc *sc; | |
212 | struct sbus_attach_args *sa; | 212 | struct sbus_attach_args *sa; | |
213 | bus_space_handle_t bh; | 213 | bus_space_handle_t bh; | |
214 | bus_space_tag_t bt; | 214 | bus_space_tag_t bt; | |
215 | struct fbdevice *fb; | 215 | struct fbdevice *fb; | |
216 | #if NWSDISPLAY > 0 | 216 | #if NWSDISPLAY > 0 | |
217 | struct wsemuldisplaydev_attach_args aa; | 217 | struct wsemuldisplaydev_attach_args aa; | |
218 | struct rasops_info *ri = &zx_console_screen.scr_ri; | 218 | struct rasops_info *ri = &zx_console_screen.scr_ri; | |
219 | unsigned long defattr; | 219 | unsigned long defattr; | |
220 | #endif | 220 | #endif | |
221 | int isconsole, width, height; | 221 | int isconsole, width, height; | |
222 | 222 | |||
223 | sc = device_private(self); | 223 | sc = device_private(self); | |
224 | sc->sc_dv = self; | 224 | sc->sc_dv = self; | |
225 | 225 | |||
226 | sa = args; | 226 | sa = args; | |
227 | fb = &sc->sc_fb; | 227 | fb = &sc->sc_fb; | |
228 | bt = sa->sa_bustag; | 228 | bt = sa->sa_bustag; | |
229 | sc->sc_bt = bt; | 229 | sc->sc_bt = bt; | |
230 | sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset); | 230 | sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset); | |
231 | 231 | |||
232 | if (sparc_bus_map_large(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0, | 232 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0, | |
233 | 0x800000, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 233 | 0x800000, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, &bh) != 0) { | |
234 | aprint_error_dev(self, "can't map bits\n"); | 234 | aprint_error_dev(self, "can't map bits\n"); | |
235 | return; | 235 | return; | |
236 | } | 236 | } | |
237 | fb->fb_pixels = (void *)bus_space_vaddr(bt, bh); | 237 | fb->fb_pixels = (void *)bus_space_vaddr(bt, bh); | |
238 | sc->sc_pixels = (u_int32_t *)fb->fb_pixels; | 238 | sc->sc_pixels = (u_int32_t *)fb->fb_pixels; | |
239 | 239 | |||
240 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR, | 240 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR, | |
241 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 241 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
242 | aprint_error_dev(self, "can't map zc\n"); | 242 | aprint_error_dev(self, "can't map zc\n"); | |
243 | return; | 243 | return; | |
244 | } | 244 | } | |
245 | 245 | |||
246 | sc->sc_bhzc = bh; | 246 | sc->sc_bhzc = bh; | |
247 | 247 | |||
248 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0, | 248 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0, | |
249 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 249 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
250 | aprint_error_dev(self, "can't map ld/ss0\n"); | 250 | aprint_error_dev(self, "can't map ld/ss0\n"); | |
251 | return; | 251 | return; | |
252 | } | 252 | } | |
253 | sc->sc_bhzdss0 = bh; | 253 | sc->sc_bhzdss0 = bh; | |
254 | 254 | |||
255 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1, | 255 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1, | |
256 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 256 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
257 | aprint_error_dev(self, "can't map ld/ss1\n"); | 257 | aprint_error_dev(self, "can't map ld/ss1\n"); | |
258 | return; | 258 | return; | |
259 | } | 259 | } | |
260 | sc->sc_bhzdss1 = bh; | 260 | sc->sc_bhzdss1 = bh; | |
261 | 261 | |||
262 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS, | 262 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS, | |
263 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 263 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
264 | aprint_error_dev(self, "can't map zx\n"); | 264 | aprint_error_dev(self, "can't map zx\n"); | |
265 | return; | 265 | return; | |
266 | } | 266 | } | |
267 | sc->sc_bhzx = bh; | 267 | sc->sc_bhzx = bh; | |
268 | 268 | |||
269 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR, | 269 | if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR, | |
270 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | 270 | PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { | |
271 | aprint_error_dev(self, "can't map zcu\n"); | 271 | aprint_error_dev(self, "can't map zcu\n"); | |
272 | return; | 272 | return; | |
273 | } | 273 | } | |
274 | sc->sc_bhzcu = bh; | 274 | sc->sc_bhzcu = bh; | |
275 | 275 | |||
276 | fb->fb_driver = &zx_fbdriver; | 276 | fb->fb_driver = &zx_fbdriver; | |
277 | fb->fb_device = sc->sc_dv; | 277 | fb->fb_device = sc->sc_dv; | |
278 | fb->fb_flags = device_cfdata(sc->sc_dv)->cf_flags & FB_USERMASK; | 278 | fb->fb_flags = device_cfdata(sc->sc_dv)->cf_flags & FB_USERMASK; | |
279 | fb->fb_pfour = NULL; | 279 | fb->fb_pfour = NULL; | |
280 | fb->fb_linebytes = prom_getpropint(sa->sa_node, "linebytes", 8192); | 280 | fb->fb_linebytes = prom_getpropint(sa->sa_node, "linebytes", 8192); | |
281 | 281 | |||
282 | width = prom_getpropint(sa->sa_node, "width", 1280); | 282 | width = prom_getpropint(sa->sa_node, "width", 1280); | |
283 | height = prom_getpropint(sa->sa_node, "height", 1024); | 283 | height = prom_getpropint(sa->sa_node, "height", 1024); | |
284 | fb_setsize_obp(fb, 32, width, height, sa->sa_node); | 284 | fb_setsize_obp(fb, 32, width, height, sa->sa_node); | |
285 | 285 | |||
286 | fb->fb_type.fb_cmsize = 256; | 286 | fb->fb_type.fb_cmsize = 256; | |
287 | fb->fb_type.fb_depth = 32; | 287 | fb->fb_type.fb_depth = 32; | |
288 | fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; | 288 | fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; | |
289 | fb->fb_type.fb_type = FBTYPE_SUNLEO; | 289 | fb->fb_type.fb_type = FBTYPE_SUNLEO; | |
290 | 290 | |||
291 | printf(": %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height); | 291 | printf(": %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height); | |
292 | isconsole = fb_is_console(sa->sa_node); | 292 | isconsole = fb_is_console(sa->sa_node); | |
293 | if (isconsole) | 293 | if (isconsole) | |
294 | printf(" (console)"); | 294 | printf(" (console)"); | |
295 | printf("\n"); | 295 | printf("\n"); | |
296 | 296 | |||
297 | sbus_establish(&sc->sc_sd, sc->sc_dv); | 297 | sbus_establish(&sc->sc_sd, sc->sc_dv); | |
298 | if (sa->sa_nintr != 0) | 298 | if (sa->sa_nintr != 0) | |
299 | bus_intr_establish(bt, sa->sa_pri, IPL_NONE, zx_intr, sc); | 299 | bus_intr_establish(bt, sa->sa_pri, IPL_NONE, zx_intr, sc); | |
300 | 300 | |||
301 | sc->sc_cmap = malloc(768, M_DEVBUF, M_NOWAIT); | 301 | sc->sc_cmap = malloc(768, M_DEVBUF, M_NOWAIT); | |
302 | zx_reset(sc); | 302 | zx_reset(sc); | |
303 | 303 | |||
304 | #if NWSDISPLAY > 0 | 304 | #if NWSDISPLAY > 0 | |
305 | sc->sc_width = fb->fb_type.fb_width; | 305 | sc->sc_width = fb->fb_type.fb_width; | |
306 | sc->sc_stride = 8192; /* 32 bit */ | 306 | sc->sc_stride = 8192; /* 32 bit */ | |
307 | sc->sc_height = fb->fb_type.fb_height; | 307 | sc->sc_height = fb->fb_type.fb_height; | |
308 | 308 | |||
309 | /* setup rasops and so on for wsdisplay */ | 309 | /* setup rasops and so on for wsdisplay */ | |
310 | wsfont_init(); | 310 | wsfont_init(); | |
311 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | 311 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | |
312 | sc->sc_bg = WS_DEFAULT_BG; | 312 | sc->sc_bg = WS_DEFAULT_BG; | |
313 | 313 | |||
314 | vcons_init(&sc->vd, sc, &zx_defaultscreen, &zx_accessops); | 314 | vcons_init(&sc->vd, sc, &zx_defaultscreen, &zx_accessops); | |
315 | sc->vd.init_screen = zx_init_screen; | 315 | sc->vd.init_screen = zx_init_screen; | |
316 | 316 | |||
317 | if (isconsole) { | 317 | if (isconsole) { | |
318 | /* we mess with zx_console_screen only once */ | 318 | /* we mess with zx_console_screen only once */ | |
319 | vcons_init_screen(&sc->vd, &zx_console_screen, 1, | 319 | vcons_init_screen(&sc->vd, &zx_console_screen, 1, | |
320 | &defattr); | 320 | &defattr); | |
321 | zx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | 321 | zx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | |
322 | 322 | |||
323 | zx_defaultscreen.textops = &ri->ri_ops; | 323 | zx_defaultscreen.textops = &ri->ri_ops; | |
324 | zx_defaultscreen.capabilities = WSSCREEN_WSCOLORS; | 324 | zx_defaultscreen.capabilities = WSSCREEN_WSCOLORS; | |
325 | zx_defaultscreen.nrows = ri->ri_rows; | 325 | zx_defaultscreen.nrows = ri->ri_rows; | |
326 | zx_defaultscreen.ncols = ri->ri_cols; | 326 | zx_defaultscreen.ncols = ri->ri_cols; | |
327 | zx_fillrect(sc, 0, 0, width, height, | 327 | zx_fillrect(sc, 0, 0, width, height, | |
328 | ri->ri_devcmap[defattr >> 16], ZX_STD_ROP); | 328 | ri->ri_devcmap[defattr >> 16], ZX_STD_ROP); | |
329 | wsdisplay_cnattach(&zx_defaultscreen, ri, 0, 0, defattr); | 329 | wsdisplay_cnattach(&zx_defaultscreen, ri, 0, 0, defattr); | |
330 | } else { | 330 | } else { | |
331 | /* | 331 | /* | |
332 | * we're not the console so we just clear the screen and don't | 332 | * we're not the console so we just clear the screen and don't | |
333 | * set up any sort of text display | 333 | * set up any sort of text display | |
334 | */ | 334 | */ | |
335 | if (zx_defaultscreen.textops == NULL) { | 335 | if (zx_defaultscreen.textops == NULL) { | |
336 | /* | 336 | /* | |
337 | * ugly, but... | 337 | * ugly, but... | |
338 | * we want the console settings to win, so we only | 338 | * we want the console settings to win, so we only | |
339 | * touch anything when we find an untouched screen | 339 | * touch anything when we find an untouched screen | |
340 | * definition. In this case we fill it from fb to | 340 | * definition. In this case we fill it from fb to | |
341 | * avoid problems in case no zx is the console | 341 | * avoid problems in case no zx is the console | |
342 | */ | 342 | */ | |
343 | ri = &sc->sc_fb.fb_rinfo; | 343 | ri = &sc->sc_fb.fb_rinfo; | |
344 | zx_defaultscreen.textops = &ri->ri_ops; | 344 | zx_defaultscreen.textops = &ri->ri_ops; | |
345 | zx_defaultscreen.capabilities = ri->ri_caps; | 345 | zx_defaultscreen.capabilities = ri->ri_caps; | |
346 | zx_defaultscreen.nrows = ri->ri_rows; | 346 | zx_defaultscreen.nrows = ri->ri_rows; | |
347 | zx_defaultscreen.ncols = ri->ri_cols; | 347 | zx_defaultscreen.ncols = ri->ri_cols; | |
348 | } | 348 | } | |
349 | } | 349 | } | |
350 | 350 | |||
351 | aa.scrdata = &zx_screenlist; | 351 | aa.scrdata = &zx_screenlist; | |
352 | aa.console = isconsole; | 352 | aa.console = isconsole; | |
353 | aa.accessops = &zx_accessops; | 353 | aa.accessops = &zx_accessops; | |
354 | aa.accesscookie = &sc->vd; | 354 | aa.accesscookie = &sc->vd; | |
355 | config_found(sc->sc_dv, &aa, wsemuldisplaydevprint); | 355 | config_found(sc->sc_dv, &aa, wsemuldisplaydevprint); | |
356 | #endif | 356 | #endif | |
357 | fb_attach(&sc->sc_fb, isconsole); | 357 | fb_attach(&sc->sc_fb, isconsole); | |
358 | } | 358 | } | |
359 | 359 | |||
360 | static int | 360 | static int | |
361 | zxopen(dev_t dev, int flags, int mode, struct lwp *l) | 361 | zxopen(dev_t dev, int flags, int mode, struct lwp *l) | |
362 | { | 362 | { | |
363 | 363 | |||
364 | if (device_lookup(&zx_cd, minor(dev)) == NULL) | 364 | if (device_lookup(&zx_cd, minor(dev)) == NULL) | |
365 | return (ENXIO); | 365 | return (ENXIO); | |
366 | return (0); | 366 | return (0); | |
367 | } | 367 | } | |
368 | 368 | |||
369 | static int | 369 | static int | |
370 | zxclose(dev_t dev, int flags, int mode, struct lwp *l) | 370 | zxclose(dev_t dev, int flags, int mode, struct lwp *l) | |
371 | { | 371 | { | |
372 | struct zx_softc *sc; | 372 | struct zx_softc *sc; | |
373 | 373 | |||
374 | sc = device_lookup_private(&zx_cd, minor(dev)); | 374 | sc = device_lookup_private(&zx_cd, minor(dev)); | |
375 | 375 | |||
376 | zx_reset(sc); | 376 | zx_reset(sc); | |
377 | zx_cursor_blank(sc); | 377 | zx_cursor_blank(sc); | |
378 | return (0); | 378 | return (0); | |
379 | } | 379 | } | |
380 | 380 | |||
381 | static int | 381 | static int | |
382 | zxioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) | 382 | zxioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) | |
383 | { | 383 | { | |
384 | struct zx_softc *sc; | 384 | struct zx_softc *sc; | |
385 | struct fbcmap *cm; | 385 | struct fbcmap *cm; | |
386 | struct fbcursor *cu; | 386 | struct fbcursor *cu; | |
387 | uint32_t curbits[2][32]; | 387 | uint32_t curbits[2][32]; | |
388 | int rv, v, count, i; | 388 | int rv, v, count, i; | |
389 | 389 | |||
390 | sc = device_lookup_private(&zx_cd, minor(dev)); | 390 | sc = device_lookup_private(&zx_cd, minor(dev)); | |
391 | 391 | |||
392 | switch (cmd) { | 392 | switch (cmd) { | |
393 | case FBIOGTYPE: | 393 | case FBIOGTYPE: | |
394 | *(struct fbtype *)data = sc->sc_fb.fb_type; | 394 | *(struct fbtype *)data = sc->sc_fb.fb_type; | |
395 | break; | 395 | break; | |
396 | 396 | |||
397 | case FBIOGATTR: | 397 | case FBIOGATTR: | |
398 | #define fba ((struct fbgattr *)data) | 398 | #define fba ((struct fbgattr *)data) | |
399 | fba->real_type = sc->sc_fb.fb_type.fb_type; | 399 | fba->real_type = sc->sc_fb.fb_type.fb_type; | |
400 | fba->owner = 0; /* XXX ??? */ | 400 | fba->owner = 0; /* XXX ??? */ | |
401 | fba->fbtype = sc->sc_fb.fb_type; | 401 | fba->fbtype = sc->sc_fb.fb_type; | |
402 | fba->sattr.flags = 0; | 402 | fba->sattr.flags = 0; | |
403 | fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; | 403 | fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; | |
404 | fba->sattr.dev_specific[0] = -1; | 404 | fba->sattr.dev_specific[0] = -1; | |
405 | fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; | 405 | fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; | |
406 | fba->emu_types[1] = -1; | 406 | fba->emu_types[1] = -1; | |
407 | fba->emu_types[2] = -1; | 407 | fba->emu_types[2] = -1; | |
408 | #undef fba | 408 | #undef fba | |
409 | break; | 409 | break; | |
410 | 410 | |||
411 | case FBIOGVIDEO: | 411 | case FBIOGVIDEO: | |
412 | *(int *)data = ((sc->sc_flags & ZX_BLANKED) != 0); | 412 | *(int *)data = ((sc->sc_flags & ZX_BLANKED) != 0); | |
413 | break; | 413 | break; | |
414 | 414 | |||
415 | case FBIOSVIDEO: | 415 | case FBIOSVIDEO: | |
416 | if (*(int *)data) | 416 | if (*(int *)data) | |
417 | zx_unblank(sc->sc_dv); | 417 | zx_unblank(sc->sc_dv); | |
418 | else | 418 | else | |
419 | zx_blank(sc->sc_dv); | 419 | zx_blank(sc->sc_dv); | |
420 | break; | 420 | break; | |
421 | 421 | |||
422 | case FBIOGETCMAP: | 422 | case FBIOGETCMAP: | |
423 | cm = (struct fbcmap *)data; | 423 | cm = (struct fbcmap *)data; | |
424 | if (cm->index > 256 || cm->count > 256 - cm->index) | 424 | if (cm->index > 256 || cm->count > 256 - cm->index) | |
425 | return (EINVAL); | 425 | return (EINVAL); | |
426 | rv = copyout(sc->sc_cmap + cm->index, cm->red, cm->count); | 426 | rv = copyout(sc->sc_cmap + cm->index, cm->red, cm->count); | |
427 | if (rv == 0) | 427 | if (rv == 0) | |
428 | rv = copyout(sc->sc_cmap + 256 + cm->index, cm->green, | 428 | rv = copyout(sc->sc_cmap + 256 + cm->index, cm->green, | |
429 | cm->count); | 429 | cm->count); | |
430 | if (rv == 0) | 430 | if (rv == 0) | |
431 | rv = copyout(sc->sc_cmap + 512 + cm->index, cm->blue, | 431 | rv = copyout(sc->sc_cmap + 512 + cm->index, cm->blue, | |
432 | cm->count); | 432 | cm->count); | |
433 | return (rv); | 433 | return (rv); | |
434 | 434 | |||
435 | case FBIOPUTCMAP: | 435 | case FBIOPUTCMAP: | |
436 | cm = (struct fbcmap *)data; | 436 | cm = (struct fbcmap *)data; | |
437 | if (cm->index > 256 || cm->count > 256 - cm->index) | 437 | if (cm->index > 256 || cm->count > 256 - cm->index) | |
438 | return (EINVAL); | 438 | return (EINVAL); | |
439 | rv = copyin(cm->red, sc->sc_cmap + cm->index, cm->count); | 439 | rv = copyin(cm->red, sc->sc_cmap + cm->index, cm->count); | |
440 | if (rv == 0) | 440 | if (rv == 0) | |
441 | rv = copyin(cm->green, sc->sc_cmap + 256 + cm->index, | 441 | rv = copyin(cm->green, sc->sc_cmap + 256 + cm->index, | |
442 | cm->count); | 442 | cm->count); | |
443 | if (rv == 0) | 443 | if (rv == 0) | |
444 | rv = copyin(cm->blue, sc->sc_cmap + 512 + cm->index, | 444 | rv = copyin(cm->blue, sc->sc_cmap + 512 + cm->index, | |
445 | cm->count); | 445 | cm->count); | |
446 | zx_cmap_put(sc); | 446 | zx_cmap_put(sc); | |
447 | return (rv); | 447 | return (rv); | |
448 | 448 | |||
449 | case FBIOGCURPOS: | 449 | case FBIOGCURPOS: | |
450 | *(struct fbcurpos *)data = sc->sc_curpos; | 450 | *(struct fbcurpos *)data = sc->sc_curpos; | |
451 | break; | 451 | break; | |
452 | 452 | |||
453 | case FBIOSCURPOS: | 453 | case FBIOSCURPOS: | |
454 | sc->sc_curpos = *(struct fbcurpos *)data; | 454 | sc->sc_curpos = *(struct fbcurpos *)data; | |
455 | zx_cursor_move(sc); | 455 | zx_cursor_move(sc); | |
456 | break; | 456 | break; | |
457 | 457 | |||
458 | case FBIOGCURMAX: | 458 | case FBIOGCURMAX: | |
459 | ((struct fbcurpos *)data)->x = 32; | 459 | ((struct fbcurpos *)data)->x = 32; | |
460 | ((struct fbcurpos *)data)->y = 32; | 460 | ((struct fbcurpos *)data)->y = 32; | |
461 | break; | 461 | break; | |
462 | 462 | |||
463 | case FBIOSCURSOR: | 463 | case FBIOSCURSOR: | |
464 | cu = (struct fbcursor *)data; | 464 | cu = (struct fbcursor *)data; | |
465 | v = cu->set; | 465 | v = cu->set; | |
466 | 466 | |||
467 | if ((v & FB_CUR_SETSHAPE) != 0) { | 467 | if ((v & FB_CUR_SETSHAPE) != 0) { | |
468 | if ((u_int)cu->size.x > 32 || (u_int)cu->size.y > 32) | 468 | if ((u_int)cu->size.x > 32 || (u_int)cu->size.y > 32) | |
469 | return (EINVAL); | 469 | return (EINVAL); | |
470 | count = cu->size.y * 4; | 470 | count = cu->size.y * 4; | |
471 | rv = copyin(cu->mask, curbits[0], count); | 471 | rv = copyin(cu->mask, curbits[0], count); | |
472 | if (rv) | 472 | if (rv) | |
473 | return rv; | 473 | return rv; | |
474 | rv = copyin(cu->image, curbits[1], count); | 474 | rv = copyin(cu->image, curbits[1], count); | |
475 | if (rv) | 475 | if (rv) | |
476 | return rv; | 476 | return rv; | |
477 | } | 477 | } | |
478 | if ((v & FB_CUR_SETCUR) != 0) { | 478 | if ((v & FB_CUR_SETCUR) != 0) { | |
479 | if (cu->enable) | 479 | if (cu->enable) | |
480 | zx_cursor_unblank(sc); | 480 | zx_cursor_unblank(sc); | |
481 | else | 481 | else | |
482 | zx_cursor_blank(sc); | 482 | zx_cursor_blank(sc); | |
483 | } | 483 | } | |
484 | if ((v & (FB_CUR_SETPOS | FB_CUR_SETHOT)) != 0) { | 484 | if ((v & (FB_CUR_SETPOS | FB_CUR_SETHOT)) != 0) { | |
485 | if ((v & FB_CUR_SETPOS) != 0) | 485 | if ((v & FB_CUR_SETPOS) != 0) | |
486 | sc->sc_curpos = cu->pos; | 486 | sc->sc_curpos = cu->pos; | |
487 | if ((v & FB_CUR_SETHOT) != 0) | 487 | if ((v & FB_CUR_SETHOT) != 0) | |
488 | sc->sc_curhot = cu->hot; | 488 | sc->sc_curhot = cu->hot; | |
489 | zx_cursor_move(sc); | 489 | zx_cursor_move(sc); | |
490 | } | 490 | } | |
491 | if ((v & FB_CUR_SETCMAP) != 0) { | 491 | if ((v & FB_CUR_SETCMAP) != 0) { | |
492 | if (cu->cmap.index > 2 || | 492 | if (cu->cmap.index > 2 || | |
493 | cu->cmap.count > 2 - cu->cmap.index) | 493 | cu->cmap.count > 2 - cu->cmap.index) | |
494 | return (EINVAL); | 494 | return (EINVAL); | |
495 | for (i = 0; i < cu->cmap.count; i++) { | 495 | for (i = 0; i < cu->cmap.count; i++) { | |
496 | if ((v = fubyte(&cu->cmap.red[i])) < 0) | 496 | if ((v = fubyte(&cu->cmap.red[i])) < 0) | |
497 | return (EFAULT); | 497 | return (EFAULT); | |
498 | sc->sc_curcmap[i + cu->cmap.index + 0] = v; | 498 | sc->sc_curcmap[i + cu->cmap.index + 0] = v; | |
499 | if ((v = fubyte(&cu->cmap.green[i])) < 0) | 499 | if ((v = fubyte(&cu->cmap.green[i])) < 0) | |
500 | return (EFAULT); | 500 | return (EFAULT); | |
501 | sc->sc_curcmap[i + cu->cmap.index + 2] = v; | 501 | sc->sc_curcmap[i + cu->cmap.index + 2] = v; | |
502 | if ((v = fubyte(&cu->cmap.blue[i])) < 0) | 502 | if ((v = fubyte(&cu->cmap.blue[i])) < 0) | |
503 | return (EFAULT); | 503 | return (EFAULT); | |
504 | sc->sc_curcmap[i + cu->cmap.index + 4] = v; | 504 | sc->sc_curcmap[i + cu->cmap.index + 4] = v; | |
505 | } | 505 | } | |
506 | zx_cursor_color(sc); | 506 | zx_cursor_color(sc); | |
507 | } | 507 | } | |
508 | if ((v & FB_CUR_SETSHAPE) != 0) { | 508 | if ((v & FB_CUR_SETSHAPE) != 0) { | |
509 | sc->sc_cursize = cu->size; | 509 | sc->sc_cursize = cu->size; | |
510 | count = cu->size.y * 4; | 510 | count = cu->size.y * 4; | |
511 | memset(sc->sc_curbits, 0, sizeof(sc->sc_curbits)); | 511 | memset(sc->sc_curbits, 0, sizeof(sc->sc_curbits)); | |
512 | memcpy(sc->sc_curbits[0], curbits[0], count); | 512 | memcpy(sc->sc_curbits[0], curbits[0], count); | |
513 | memcpy(sc->sc_curbits[1], curbits[1], count); | 513 | memcpy(sc->sc_curbits[1], curbits[1], count); | |
514 | zx_cursor_set(sc); | 514 | zx_cursor_set(sc); | |
515 | } | 515 | } | |
516 | break; | 516 | break; | |
517 | 517 | |||
518 | case FBIOGCURSOR: | 518 | case FBIOGCURSOR: | |
519 | cu = (struct fbcursor *)data; | 519 | cu = (struct fbcursor *)data; | |
520 | 520 | |||
521 | cu->set = FB_CUR_SETALL; | 521 | cu->set = FB_CUR_SETALL; | |
522 | cu->enable = ((sc->sc_flags & ZX_CURSOR) != 0); | 522 | cu->enable = ((sc->sc_flags & ZX_CURSOR) != 0); | |
523 | cu->pos = sc->sc_curpos; | 523 | cu->pos = sc->sc_curpos; | |
524 | cu->hot = sc->sc_curhot; | 524 | cu->hot = sc->sc_curhot; | |
525 | cu->size = sc->sc_cursize; | 525 | cu->size = sc->sc_cursize; | |
526 | 526 | |||
527 | if (cu->image != NULL) { | 527 | if (cu->image != NULL) { | |
528 | count = sc->sc_cursize.y * 4; | 528 | count = sc->sc_cursize.y * 4; | |
529 | rv = copyout(sc->sc_curbits[1], cu->image, count); | 529 | rv = copyout(sc->sc_curbits[1], cu->image, count); | |
530 | if (rv) | 530 | if (rv) | |
531 | return (rv); | 531 | return (rv); | |
532 | rv = copyout(sc->sc_curbits[0], cu->mask, count); | 532 | rv = copyout(sc->sc_curbits[0], cu->mask, count); | |
533 | if (rv) | 533 | if (rv) | |
534 | return (rv); | 534 | return (rv); | |
535 | } | 535 | } | |
536 | if (cu->cmap.red != NULL) { | 536 | if (cu->cmap.red != NULL) { | |
537 | if (cu->cmap.index > 2 || | 537 | if (cu->cmap.index > 2 || | |
538 | cu->cmap.count > 2 - cu->cmap.index) | 538 | cu->cmap.count > 2 - cu->cmap.index) | |
539 | return (EINVAL); | 539 | return (EINVAL); | |
540 | for (i = 0; i < cu->cmap.count; i++) { | 540 | for (i = 0; i < cu->cmap.count; i++) { | |
541 | v = sc->sc_curcmap[i + cu->cmap.index + 0]; | 541 | v = sc->sc_curcmap[i + cu->cmap.index + 0]; | |
542 | if (subyte(&cu->cmap.red[i], v)) | 542 | if (subyte(&cu->cmap.red[i], v)) | |
543 | return (EFAULT); | 543 | return (EFAULT); | |
544 | v = sc->sc_curcmap[i + cu->cmap.index + 2]; | 544 | v = sc->sc_curcmap[i + cu->cmap.index + 2]; | |
545 | if (subyte(&cu->cmap.green[i], v)) | 545 | if (subyte(&cu->cmap.green[i], v)) | |
546 | return (EFAULT); | 546 | return (EFAULT); | |
547 | v = sc->sc_curcmap[i + cu->cmap.index + 4]; | 547 | v = sc->sc_curcmap[i + cu->cmap.index + 4]; | |
548 | if (subyte(&cu->cmap.blue[i], v)) | 548 | if (subyte(&cu->cmap.blue[i], v)) | |
549 | return (EFAULT); | 549 | return (EFAULT); | |
550 | } | 550 | } | |
551 | } else { | 551 | } else { | |
552 | cu->cmap.index = 0; | 552 | cu->cmap.index = 0; | |
553 | cu->cmap.count = 2; | 553 | cu->cmap.count = 2; | |
554 | } | 554 | } | |
555 | break; | 555 | break; | |
556 | 556 | |||
557 | default: | 557 | default: | |
558 | #ifdef DEBUG | 558 | #ifdef DEBUG | |
559 | log(LOG_NOTICE, "zxioctl(0x%lx) (%s[%d])\n", cmd, | 559 | log(LOG_NOTICE, "zxioctl(0x%lx) (%s[%d])\n", cmd, | |
560 | l->l_proc->p_comm, l->l_proc->p_pid); | 560 | l->l_proc->p_comm, l->l_proc->p_pid); | |
561 | #endif | 561 | #endif | |
562 | return (ENOTTY); | 562 | return (ENOTTY); | |
563 | } | 563 | } | |
564 | 564 | |||
565 | return (0); | 565 | return (0); | |
566 | } | 566 | } | |
567 | 567 | |||
568 | static int | 568 | static int | |
569 | zx_intr(void *cookie) | 569 | zx_intr(void *cookie) | |
570 | { | 570 | { | |
571 | 571 | |||
572 | return (1); | 572 | return (1); | |
573 | } | 573 | } | |
574 | 574 | |||
575 | static void | 575 | static void | |
576 | zx_reset(struct zx_softc *sc) | 576 | zx_reset(struct zx_softc *sc) | |
577 | { | 577 | { | |
578 | struct fbtype *fbt; | 578 | struct fbtype *fbt; | |
579 | u_int i; | 579 | u_int i; | |
580 | 580 | |||
581 | fbt = &sc->sc_fb.fb_type; | 581 | fbt = &sc->sc_fb.fb_type; | |
582 | 582 | |||
583 | zx_cross_loadwid(sc, ZX_WID_DBL_8, 0, 0x2c0); | 583 | zx_cross_loadwid(sc, ZX_WID_DBL_8, 0, 0x2c0); | |
584 | zx_cross_loadwid(sc, ZX_WID_DBL_8, 1, 0x30); | 584 | zx_cross_loadwid(sc, ZX_WID_DBL_8, 1, 0x30); | |
585 | zx_cross_loadwid(sc, ZX_WID_DBL_8, 2, 0x20); | 585 | zx_cross_loadwid(sc, ZX_WID_DBL_8, 2, 0x20); | |
586 | zx_cross_loadwid(sc, ZX_WID_DBL_24, 1, 0x30); | 586 | zx_cross_loadwid(sc, ZX_WID_DBL_24, 1, 0x30); | |
587 | 587 | |||
588 | i = bus_space_read_4(sc->sc_bt, sc->sc_bhzdss1, zd_misc); | 588 | i = bus_space_read_4(sc->sc_bt, sc->sc_bhzdss1, zd_misc); | |
589 | i |= ZX_SS1_MISC_ENABLE; | 589 | i |= ZX_SS1_MISC_ENABLE; | |
590 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss1, zd_misc, i); | 590 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss1, zd_misc, i); | |
591 | 591 | |||
592 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_wid, 1); | 592 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_wid, 1); | |
593 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_widclip, 0); | 593 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_widclip, 0); | |
594 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_wmask, 0xffff); | 594 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_wmask, 0xffff); | |
595 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_vclipmin, 0); | 595 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_vclipmin, 0); | |
596 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_vclipmax, | 596 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_vclipmax, | |
597 | (fbt->fb_width - 1) | ((fbt->fb_height - 1) << 16)); | 597 | (fbt->fb_width - 1) | ((fbt->fb_height - 1) << 16)); | |
598 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_fg, 0); | 598 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_fg, 0); | |
599 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_planemask, 0xffffffff); | 599 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_planemask, 0xffffffff); | |
600 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, ZX_STD_ROP); | 600 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, ZX_STD_ROP); | |
601 | 601 | |||
602 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_extent, | 602 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_extent, | |
603 | (fbt->fb_width - 1) | ((fbt->fb_height - 1) << 11)); | 603 | (fbt->fb_width - 1) | ((fbt->fb_height - 1) << 11)); | |
604 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_addrspace, | 604 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_addrspace, | |
605 | ZX_ADDRSPC_FONT_OBGR); | 605 | ZX_ADDRSPC_FONT_OBGR); | |
606 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_fontt, 0); | 606 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_fontt, 0); | |
607 | 607 | |||
608 | for (i = 0; i < 256; i++) { | 608 | for (i = 0; i < 256; i++) { | |
609 | sc->sc_cmap[i] = rasops_cmap[i * 3]; | 609 | sc->sc_cmap[i] = rasops_cmap[i * 3]; | |
610 | sc->sc_cmap[i + 256] = rasops_cmap[i * 3 + 1]; | 610 | sc->sc_cmap[i + 256] = rasops_cmap[i * 3 + 1]; | |
611 | sc->sc_cmap[i + 512] = rasops_cmap[i * 3 + 2]; | 611 | sc->sc_cmap[i + 512] = rasops_cmap[i * 3 + 2]; | |
612 | } | 612 | } | |
613 | 613 | |||
614 | zx_cmap_put(sc); | 614 | zx_cmap_put(sc); | |
615 | } | 615 | } | |
616 | 616 | |||
617 | static int | 617 | static int | |
618 | zx_cross_wait(struct zx_softc *sc) | 618 | zx_cross_wait(struct zx_softc *sc) | |
619 | { | 619 | { | |
620 | int i; | 620 | int i; | |
621 | 621 | |||
622 | for (i = 300000; i != 0; i--) { | 622 | for (i = 300000; i != 0; i--) { | |
623 | if ((bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr) & | 623 | if ((bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr) & | |
624 | ZX_CROSS_CSR_PROGRESS) == 0) | 624 | ZX_CROSS_CSR_PROGRESS) == 0) | |
625 | break; | 625 | break; | |
626 | DELAY(1); | 626 | DELAY(1); | |
627 | } | 627 | } | |
628 | 628 | |||
629 | if (i == 0) | 629 | if (i == 0) | |
630 | printf("zx_cross_wait: timed out\n"); | 630 | printf("zx_cross_wait: timed out\n"); | |
631 | 631 | |||
632 | return (i); | 632 | return (i); | |
633 | } | 633 | } | |
634 | 634 | |||
635 | static int | 635 | static int | |
636 | zx_cross_loadwid(struct zx_softc *sc, u_int type, u_int index, u_int value) | 636 | zx_cross_loadwid(struct zx_softc *sc, u_int type, u_int index, u_int value) | |
637 | { | 637 | { | |
638 | u_int tmp = 0; | 638 | u_int tmp = 0; | |
639 | 639 | |||
640 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_WID); | 640 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_WID); | |
641 | 641 | |||
642 | if (zx_cross_wait(sc)) | 642 | if (zx_cross_wait(sc)) | |
643 | return (1); | 643 | return (1); | |
644 | 644 | |||
645 | if (type == ZX_WID_DBL_8) | 645 | if (type == ZX_WID_DBL_8) | |
646 | tmp = (index & 0x0f) + 0x40; | 646 | tmp = (index & 0x0f) + 0x40; | |
647 | else if (type == ZX_WID_DBL_24) | 647 | else if (type == ZX_WID_DBL_24) | |
648 | tmp = index & 0x3f; | 648 | tmp = index & 0x3f; | |
649 | 649 | |||
650 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, 0x5800 + tmp); | 650 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, 0x5800 + tmp); | |
651 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_value, value); | 651 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_value, value); | |
652 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_WID); | 652 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_WID); | |
653 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, | 653 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, | |
654 | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2); | 654 | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2); | |
655 | 655 | |||
656 | return (0); | 656 | return (0); | |
657 | } | 657 | } | |
658 | 658 | |||
659 | static int | 659 | static int | |
660 | zx_cmap_put(struct zx_softc *sc) | 660 | zx_cmap_put(struct zx_softc *sc) | |
661 | { | 661 | { | |
662 | const u_char *b; | 662 | const u_char *b; | |
663 | u_int i, t; | 663 | u_int i, t; | |
664 | 664 | |||
665 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_CLUT0); | 665 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_CLUT0); | |
666 | 666 | |||
667 | zx_cross_wait(sc); | 667 | zx_cross_wait(sc); | |
668 | 668 | |||
669 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, | 669 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, | |
670 | ZX_CROSS_TYPE_CLUTDATA); | 670 | ZX_CROSS_TYPE_CLUTDATA); | |
671 | 671 | |||
672 | for (i = 0, b = sc->sc_cmap; i < 256; i++) { | 672 | for (i = 0, b = sc->sc_cmap; i < 256; i++) { | |
673 | t = b[i]; | 673 | t = b[i]; | |
674 | t |= b[i + 256] << 8; | 674 | t |= b[i + 256] << 8; | |
675 | t |= b[i + 512] << 16; | 675 | t |= b[i + 512] << 16; | |
676 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_value, t); | 676 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_value, t); | |
677 | } | 677 | } | |
678 | 678 | |||
679 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_CLUT0); | 679 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_CLUT0); | |
680 | i = bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr); | 680 | i = bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr); | |
681 | i = i | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2; | 681 | i = i | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2; | |
682 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, i); | 682 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, i); | |
683 | return (0); | 683 | return (0); | |
684 | } | 684 | } | |
685 | 685 | |||
686 | static void | 686 | static void | |
687 | zx_cursor_move(struct zx_softc *sc) | 687 | zx_cursor_move(struct zx_softc *sc) | |
688 | { | 688 | { | |
689 | int sx, sy, x, y; | 689 | int sx, sy, x, y; | |
690 | 690 | |||
691 | x = sc->sc_curpos.x - sc->sc_curhot.x; | 691 | x = sc->sc_curpos.x - sc->sc_curhot.x; | |
692 | y = sc->sc_curpos.y - sc->sc_curhot.y; | 692 | y = sc->sc_curpos.y - sc->sc_curhot.y; | |
693 | 693 | |||
694 | if (x < 0) { | 694 | if (x < 0) { | |
695 | sx = min(-x, 32); | 695 | sx = min(-x, 32); | |
696 | x = 0; | 696 | x = 0; | |
697 | } else | 697 | } else | |
698 | sx = 0; | 698 | sx = 0; | |
699 | 699 | |||
700 | if (y < 0) { | 700 | if (y < 0) { | |
701 | sy = min(-y, 32); | 701 | sy = min(-y, 32); | |
702 | y = 0; | 702 | y = 0; | |
703 | } else | 703 | } else | |
704 | sy = 0; | 704 | sy = 0; | |
705 | 705 | |||
706 | if (sx != sc->sc_shiftx || sy != sc->sc_shifty) { | 706 | if (sx != sc->sc_shiftx || sy != sc->sc_shifty) { | |
707 | sc->sc_shiftx = sx; | 707 | sc->sc_shiftx = sx; | |
708 | sc->sc_shifty = sy; | 708 | sc->sc_shifty = sy; | |
709 | zx_cursor_set(sc); | 709 | zx_cursor_set(sc); | |
710 | } | 710 | } | |
711 | 711 | |||
712 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_sxy, | 712 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_sxy, | |
713 | ((y & 0x7ff) << 11) | (x & 0x7ff)); | 713 | ((y & 0x7ff) << 11) | (x & 0x7ff)); | |
714 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 714 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
715 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x30); | 715 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x30); | |
716 | 716 | |||
717 | /* XXX Necessary? */ | 717 | /* XXX Necessary? */ | |
718 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 718 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
719 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x80); | 719 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x80); | |
720 | } | 720 | } | |
721 | 721 | |||
722 | static void | 722 | static void | |
723 | zx_cursor_set(struct zx_softc *sc) | 723 | zx_cursor_set(struct zx_softc *sc) | |
724 | { | 724 | { | |
725 | int i, j, data; | 725 | int i, j, data; | |
726 | 726 | |||
727 | if ((sc->sc_flags & ZX_CURSOR) != 0) | 727 | if ((sc->sc_flags & ZX_CURSOR) != 0) | |
728 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 728 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
729 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) & | 729 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) & | |
730 | ~0x80); | 730 | ~0x80); | |
731 | 731 | |||
732 | for (j = 0; j < 2; j++) { | 732 | for (j = 0; j < 2; j++) { | |
733 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_type, 0x20 << j); | 733 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_type, 0x20 << j); | |
734 | 734 | |||
735 | for (i = sc->sc_shifty; i < 32; i++) { | 735 | for (i = sc->sc_shifty; i < 32; i++) { | |
736 | data = sc->sc_curbits[j][i]; | 736 | data = sc->sc_curbits[j][i]; | |
737 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, | 737 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, | |
738 | data >> sc->sc_shiftx); | 738 | data >> sc->sc_shiftx); | |
739 | } | 739 | } | |
740 | for (i = sc->sc_shifty; i != 0; i--) | 740 | for (i = sc->sc_shifty; i != 0; i--) | |
741 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, 0); | 741 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, 0); | |
742 | } | 742 | } | |
743 | 743 | |||
744 | if ((sc->sc_flags & ZX_CURSOR) != 0) | 744 | if ((sc->sc_flags & ZX_CURSOR) != 0) | |
745 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 745 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
746 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x80); | 746 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x80); | |
747 | } | 747 | } | |
748 | 748 | |||
749 | static void | 749 | static void | |
750 | zx_cursor_blank(struct zx_softc *sc) | 750 | zx_cursor_blank(struct zx_softc *sc) | |
751 | { | 751 | { | |
752 | 752 | |||
753 | sc->sc_flags &= ~ZX_CURSOR; | 753 | sc->sc_flags &= ~ZX_CURSOR; | |
754 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 754 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
755 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) & ~0x80); | 755 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) & ~0x80); | |
756 | } | 756 | } | |
757 | 757 | |||
758 | static void | 758 | static void | |
759 | zx_cursor_unblank(struct zx_softc *sc) | 759 | zx_cursor_unblank(struct zx_softc *sc) | |
760 | { | 760 | { | |
761 | 761 | |||
762 | sc->sc_flags |= ZX_CURSOR; | 762 | sc->sc_flags |= ZX_CURSOR; | |
763 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 763 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
764 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x80); | 764 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x80); | |
765 | } | 765 | } | |
766 | 766 | |||
767 | static void | 767 | static void | |
768 | zx_cursor_color(struct zx_softc *sc) | 768 | zx_cursor_color(struct zx_softc *sc) | |
769 | { | 769 | { | |
770 | u_int8_t tmp; | 770 | u_int8_t tmp; | |
771 | 771 | |||
772 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_type, 0x50); | 772 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_type, 0x50); | |
773 | 773 | |||
774 | tmp = sc->sc_curcmap[0] | (sc->sc_curcmap[2] << 8) | | 774 | tmp = sc->sc_curcmap[0] | (sc->sc_curcmap[2] << 8) | | |
775 | (sc->sc_curcmap[4] << 16); | 775 | (sc->sc_curcmap[4] << 16); | |
776 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, tmp); | 776 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, tmp); | |
777 | 777 | |||
778 | tmp = sc->sc_curcmap[1] | (sc->sc_curcmap[3] << 8) | | 778 | tmp = sc->sc_curcmap[1] | (sc->sc_curcmap[3] << 8) | | |
779 | (sc->sc_curcmap[5] << 16); | 779 | (sc->sc_curcmap[5] << 16); | |
780 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, sc->sc_curcmap[1]); | 780 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_data, sc->sc_curcmap[1]); | |
781 | 781 | |||
782 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | 782 | bus_space_write_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc, | |
783 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x03); | 783 | bus_space_read_4(sc->sc_bt, sc->sc_bhzcu, zcu_misc) | 0x03); | |
784 | } | 784 | } | |
785 | 785 | |||
786 | static void | 786 | static void | |
787 | zx_blank(device_t dv) | 787 | zx_blank(device_t dv) | |
788 | { | 788 | { | |
789 | struct zx_softc *sc; | 789 | struct zx_softc *sc; | |
790 | 790 | |||
791 | sc = device_private(dv); | 791 | sc = device_private(dv); | |
792 | 792 | |||
793 | if ((sc->sc_flags & ZX_BLANKED) != 0) | 793 | if ((sc->sc_flags & ZX_BLANKED) != 0) | |
794 | return; | 794 | return; | |
795 | sc->sc_flags |= ZX_BLANKED; | 795 | sc->sc_flags |= ZX_BLANKED; | |
796 | 796 | |||
797 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_VIDEO); | 797 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_VIDEO); | |
798 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, | 798 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, | |
799 | bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr) & | 799 | bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr) & | |
800 | ~ZX_CROSS_CSR_ENABLE); | 800 | ~ZX_CROSS_CSR_ENABLE); | |
801 | } | 801 | } | |
802 | 802 | |||
803 | static void | 803 | static void | |
804 | zx_unblank(device_t dv) | 804 | zx_unblank(device_t dv) | |
805 | { | 805 | { | |
806 | struct zx_softc *sc; | 806 | struct zx_softc *sc; | |
807 | 807 | |||
808 | sc = device_private(dv); | 808 | sc = device_private(dv); | |
809 | 809 | |||
810 | if ((sc->sc_flags & ZX_BLANKED) == 0) | 810 | if ((sc->sc_flags & ZX_BLANKED) == 0) | |
811 | return; | 811 | return; | |
812 | sc->sc_flags &= ~ZX_BLANKED; | 812 | sc->sc_flags &= ~ZX_BLANKED; | |
813 | 813 | |||
814 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_VIDEO); | 814 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_type, ZX_CROSS_TYPE_VIDEO); | |
815 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, | 815 | bus_space_write_4(sc->sc_bt, sc->sc_bhzx, zx_csr, | |
816 | bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr) | | 816 | bus_space_read_4(sc->sc_bt, sc->sc_bhzx, zx_csr) | | |
817 | ZX_CROSS_CSR_ENABLE); | 817 | ZX_CROSS_CSR_ENABLE); | |
818 | } | 818 | } | |
819 | 819 | |||
820 | static paddr_t | 820 | static paddr_t | |
821 | zxmmap(dev_t dev, off_t off, int prot) | 821 | zxmmap(dev_t dev, off_t off, int prot) | |
822 | { | 822 | { | |
823 | struct zx_softc *sc; | 823 | struct zx_softc *sc; | |
824 | const struct zx_mmo *mm, *mmmax; | 824 | const struct zx_mmo *mm, *mmmax; | |
825 | 825 | |||
826 | sc = device_lookup_private(&zx_cd, minor(dev)); | 826 | sc = device_lookup_private(&zx_cd, minor(dev)); | |
827 | off = trunc_page(off); | 827 | off = trunc_page(off); | |
828 | mm = zx_mmo; | 828 | mm = zx_mmo; | |
829 | mmmax = mm + sizeof(zx_mmo) / sizeof(zx_mmo[0]); | 829 | mmmax = mm + sizeof(zx_mmo) / sizeof(zx_mmo[0]); | |
830 | 830 | |||
831 | for (; mm < mmmax; mm++) | 831 | for (; mm < mmmax; mm++) | |
832 | if (off >= mm->mo_va && off < mm->mo_va + mm->mo_size) { | 832 | if (off >= mm->mo_va && off < mm->mo_va + mm->mo_size) { | |
833 | off = off - mm->mo_va + mm->mo_pa; | 833 | off = off - mm->mo_va + mm->mo_pa; | |
834 | return (bus_space_mmap(sc->sc_bt, sc->sc_paddr, | 834 | return (bus_space_mmap(sc->sc_bt, sc->sc_paddr, | |
835 | off, prot, BUS_SPACE_MAP_LINEAR)); | 835 | off, prot, BUS_SPACE_MAP_LINEAR)); | |
836 | } | 836 | } | |
837 | 837 | |||
838 | return (-1); | 838 | return (-1); | |
839 | } | 839 | } | |
840 | 840 | |||
841 | static void | 841 | static void | |
842 | zx_fillrect(struct zx_softc *sc, int x, int y, int w, int h, uint32_t bg, | 842 | zx_fillrect(struct zx_softc *sc, int x, int y, int w, int h, uint32_t bg, | |
843 | int rop) | 843 | int rop) | |
844 | { | 844 | { | |
845 | 845 | |||
846 | 846 | |||
847 | while ((bus_space_read_4(sc->sc_bt, sc->sc_bhzc, zc_csr) & | 847 | while ((bus_space_read_4(sc->sc_bt, sc->sc_bhzc, zc_csr) & | |
848 | ZX_CSR_BLT_BUSY) != 0) | 848 | ZX_CSR_BLT_BUSY) != 0) | |
849 | ; | 849 | ; | |
850 | 850 | |||
851 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, rop); | 851 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, rop); | |
852 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_fg, bg); | 852 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_fg, bg); | |
853 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_extent, w | (h << 11)); | 853 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_extent, w | (h << 11)); | |
854 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_fill, | 854 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_fill, | |
855 | x | (y << 11) | 0x80000000); | 855 | x | (y << 11) | 0x80000000); | |
856 | } | 856 | } | |
857 | 857 | |||
858 | static void | 858 | static void | |
859 | zx_copyrect(struct zx_softc *sc, int sx, int sy, int dx, int dy, int w, | 859 | zx_copyrect(struct zx_softc *sc, int sx, int sy, int dx, int dy, int w, | |
860 | int h) | 860 | int h) | |
861 | { | 861 | { | |
862 | uint32_t dir; | 862 | uint32_t dir; | |
863 | 863 | |||
864 | if (sy < dy || sx < dx) { | 864 | if (sy < dy || sx < dx) { | |
865 | dir = 0x80000000; | 865 | dir = 0x80000000; | |
866 | sx += w; | 866 | sx += w; | |
867 | sy += h; | 867 | sy += h; | |
868 | dx += w; | 868 | dx += w; | |
869 | dy += h; | 869 | dy += h; | |
870 | } else | 870 | } else | |
871 | dir = 0; | 871 | dir = 0; | |
872 | 872 | |||
873 | while ((bus_space_read_4(sc->sc_bt, sc->sc_bhzc, zc_csr) & | 873 | while ((bus_space_read_4(sc->sc_bt, sc->sc_bhzc, zc_csr) & | |
874 | ZX_CSR_BLT_BUSY) != 0) | 874 | ZX_CSR_BLT_BUSY) != 0) | |
875 | ; | 875 | ; | |
876 | 876 | |||
877 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, ZX_STD_ROP); | 877 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, ZX_STD_ROP); | |
878 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_extent, | 878 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_extent, | |
879 | w | (h << 11) | dir); | 879 | w | (h << 11) | dir); | |
880 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_src, sx | (sy << 11)); | 880 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_src, sx | (sy << 11)); | |
881 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_copy, dx | (dy << 11)); | 881 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_copy, dx | (dy << 11)); | |
882 | } | 882 | } | |
883 | 883 | |||
884 | static void | 884 | static void | |
885 | zx_do_cursor(void *cookie, int on, int row, int col) | 885 | zx_do_cursor(void *cookie, int on, int row, int col) | |
886 | { | 886 | { | |
887 | struct rasops_info *ri = cookie; | 887 | struct rasops_info *ri = cookie; | |
888 | struct vcons_screen *scr = ri->ri_hw; | 888 | struct vcons_screen *scr = ri->ri_hw; | |
889 | struct zx_softc *sc = scr->scr_cookie; | 889 | struct zx_softc *sc = scr->scr_cookie; | |
890 | int x, y, wi, he; | 890 | int x, y, wi, he; | |
891 | 891 | |||
892 | wi = ri->ri_font->fontwidth; | 892 | wi = ri->ri_font->fontwidth; | |
893 | he = ri->ri_font->fontheight; | 893 | he = ri->ri_font->fontheight; | |
894 | 894 | |||
895 | if (ri->ri_flg & RI_CURSOR) { | 895 | if (ri->ri_flg & RI_CURSOR) { | |
896 | x = ri->ri_ccol * wi + ri->ri_xorigin; | 896 | x = ri->ri_ccol * wi + ri->ri_xorigin; | |
897 | y = ri->ri_crow * he + ri->ri_yorigin; | 897 | y = ri->ri_crow * he + ri->ri_yorigin; | |
898 | zx_fillrect(sc, x, y, wi, he, 0xff000000, | 898 | zx_fillrect(sc, x, y, wi, he, 0xff000000, | |
899 | ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE | | 899 | ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE | | |
900 | ZX_ATTR_FORCE_WID); | 900 | ZX_ATTR_FORCE_WID); | |
901 | ri->ri_flg &= ~RI_CURSOR; | 901 | ri->ri_flg &= ~RI_CURSOR; | |
902 | } | 902 | } | |
903 | 903 | |||
904 | ri->ri_crow = row; | 904 | ri->ri_crow = row; | |
905 | ri->ri_ccol = col; | 905 | ri->ri_ccol = col; | |
906 | 906 | |||
907 | if (on) | 907 | if (on) | |
908 | { | 908 | { | |
909 | x = ri->ri_ccol * wi + ri->ri_xorigin; | 909 | x = ri->ri_ccol * wi + ri->ri_xorigin; | |
910 | y = ri->ri_crow * he + ri->ri_yorigin; | 910 | y = ri->ri_crow * he + ri->ri_yorigin; | |
911 | zx_fillrect(sc, x, y, wi, he, 0xff000000, | 911 | zx_fillrect(sc, x, y, wi, he, 0xff000000, | |
912 | ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE | | 912 | ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE | | |
913 | ZX_ATTR_FORCE_WID); | 913 | ZX_ATTR_FORCE_WID); | |
914 | ri->ri_flg |= RI_CURSOR; | 914 | ri->ri_flg |= RI_CURSOR; | |
915 | } | 915 | } | |
916 | } | 916 | } | |
917 | 917 | |||
918 | static void | 918 | static void | |
919 | zx_erasecols(void *cookie, int row, int startcol, int ncols, long attr) | 919 | zx_erasecols(void *cookie, int row, int startcol, int ncols, long attr) | |
920 | { | 920 | { | |
921 | struct rasops_info *ri = cookie; | 921 | struct rasops_info *ri = cookie; | |
922 | struct vcons_screen *scr = ri->ri_hw; | 922 | struct vcons_screen *scr = ri->ri_hw; | |
923 | struct zx_softc *sc = scr->scr_cookie; | 923 | struct zx_softc *sc = scr->scr_cookie; | |
924 | int32_t x, y, width, height, bg; | 924 | int32_t x, y, width, height, bg; | |
925 | 925 | |||
926 | x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; | 926 | x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; | |
927 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 927 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
928 | width = ri->ri_font->fontwidth * ncols; | 928 | width = ri->ri_font->fontwidth * ncols; | |
929 | height = ri->ri_font->fontheight; | 929 | height = ri->ri_font->fontheight; | |
930 | bg = ((uint32_t)ri->ri_devcmap[(attr >> 16) & 0xff]) << 24; | 930 | bg = ((uint32_t)ri->ri_devcmap[(attr >> 16) & 0xff]) << 24; | |
931 | zx_fillrect(sc, x, y, width, height, bg, ZX_STD_ROP); | 931 | zx_fillrect(sc, x, y, width, height, bg, ZX_STD_ROP); | |
932 | } | 932 | } | |
933 | 933 | |||
934 | static void | 934 | static void | |
935 | zx_eraserows(void *cookie, int row, int nrows, long attr) | 935 | zx_eraserows(void *cookie, int row, int nrows, long attr) | |
936 | { | 936 | { | |
937 | struct rasops_info *ri = cookie; | 937 | struct rasops_info *ri = cookie; | |
938 | struct vcons_screen *scr = ri->ri_hw; | 938 | struct vcons_screen *scr = ri->ri_hw; | |
939 | struct zx_softc *sc = scr->scr_cookie; | 939 | struct zx_softc *sc = scr->scr_cookie; | |
940 | int32_t x, y, width, height, bg; | 940 | int32_t x, y, width, height, bg; | |
941 | 941 | |||
942 | if ((row == 0) && (nrows == ri->ri_rows)) { | 942 | if ((row == 0) && (nrows == ri->ri_rows)) { | |
943 | x = y = 0; | 943 | x = y = 0; | |
944 | width = ri->ri_width; | 944 | width = ri->ri_width; | |
945 | height = ri->ri_height; | 945 | height = ri->ri_height; | |
946 | } else { | 946 | } else { | |
947 | x = ri->ri_xorigin; | 947 | x = ri->ri_xorigin; | |
948 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 948 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
949 | width = ri->ri_emuwidth; | 949 | width = ri->ri_emuwidth; | |
950 | height = ri->ri_font->fontheight * nrows; | 950 | height = ri->ri_font->fontheight * nrows; | |
951 | } | 951 | } | |
952 | bg = ((uint32_t)ri->ri_devcmap[(attr >> 16) & 0xff]) << 24; | 952 | bg = ((uint32_t)ri->ri_devcmap[(attr >> 16) & 0xff]) << 24; | |
953 | zx_fillrect(sc, x, y, width, height, bg, ZX_STD_ROP); | 953 | zx_fillrect(sc, x, y, width, height, bg, ZX_STD_ROP); | |
954 | } | 954 | } | |
955 | 955 | |||
956 | static void | 956 | static void | |
957 | zx_copyrows(void *cookie, int srcrow, int dstrow, int nrows) | 957 | zx_copyrows(void *cookie, int srcrow, int dstrow, int nrows) | |
958 | { | 958 | { | |
959 | struct rasops_info *ri = cookie; | 959 | struct rasops_info *ri = cookie; | |
960 | struct vcons_screen *scr = ri->ri_hw; | 960 | struct vcons_screen *scr = ri->ri_hw; | |
961 | struct zx_softc *sc = scr->scr_cookie; | 961 | struct zx_softc *sc = scr->scr_cookie; | |
962 | int32_t x, ys, yd, width, height; | 962 | int32_t x, ys, yd, width, height; | |
963 | 963 | |||
964 | x = ri->ri_xorigin; | 964 | x = ri->ri_xorigin; | |
965 | ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; | 965 | ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; | |
966 | yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; | 966 | yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; | |
967 | width = ri->ri_emuwidth; | 967 | width = ri->ri_emuwidth; | |
968 | height = ri->ri_font->fontheight * nrows; | 968 | height = ri->ri_font->fontheight * nrows; | |
969 | zx_copyrect(sc, x, ys, x, yd, width, height); | 969 | zx_copyrect(sc, x, ys, x, yd, width, height); | |
970 | } | 970 | } | |
971 | 971 | |||
972 | static void | 972 | static void | |
973 | zx_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) | 973 | zx_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) | |
974 | { | 974 | { | |
975 | struct rasops_info *ri = cookie; | 975 | struct rasops_info *ri = cookie; | |
976 | struct vcons_screen *scr = ri->ri_hw; | 976 | struct vcons_screen *scr = ri->ri_hw; | |
977 | struct zx_softc *sc = scr->scr_cookie; | 977 | struct zx_softc *sc = scr->scr_cookie; | |
978 | int32_t xs, xd, y, width, height; | 978 | int32_t xs, xd, y, width, height; | |
979 | 979 | |||
980 | xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; | 980 | xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; | |
981 | xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; | 981 | xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; | |
982 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 982 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
983 | width = ri->ri_font->fontwidth * ncols; | 983 | width = ri->ri_font->fontwidth * ncols; | |
984 | height = ri->ri_font->fontheight; | 984 | height = ri->ri_font->fontheight; | |
985 | zx_copyrect(sc, xs, y, xd, y, width, height); | 985 | zx_copyrect(sc, xs, y, xd, y, width, height); | |
986 | } | 986 | } | |
987 | 987 | |||
988 | static void | 988 | static void | |
989 | zx_putchar(void *cookie, int row, int col, u_int uc, long attr) | 989 | zx_putchar(void *cookie, int row, int col, u_int uc, long attr) | |
990 | { | 990 | { | |
991 | struct rasops_info *ri = cookie; | 991 | struct rasops_info *ri = cookie; | |
992 | struct vcons_screen *scr = ri->ri_hw; | 992 | struct vcons_screen *scr = ri->ri_hw; | |
993 | struct zx_softc *sc = scr->scr_cookie; | 993 | struct zx_softc *sc = scr->scr_cookie; | |
994 | struct wsdisplay_font *font; | 994 | struct wsdisplay_font *font; | |
995 | volatile u_int32_t *dp; | 995 | volatile u_int32_t *dp; | |
996 | u_int8_t *fb; | 996 | u_int8_t *fb; | |
997 | int fs, i, ul; | 997 | int fs, i, ul; | |
998 | uint32_t fg, bg; | 998 | uint32_t fg, bg; | |
999 | 999 | |||
1000 | rasops_unpack_attr(attr, &fg, &bg, &ul); | 1000 | rasops_unpack_attr(attr, &fg, &bg, &ul); | |
1001 | bg = ((uint32_t)ri->ri_devcmap[bg]) << 24; | 1001 | bg = ((uint32_t)ri->ri_devcmap[bg]) << 24; | |
1002 | fg = ((uint32_t)ri->ri_devcmap[fg]) << 24; | 1002 | fg = ((uint32_t)ri->ri_devcmap[fg]) << 24; | |
1003 | if (uc == ' ') { | 1003 | if (uc == ' ') { | |
1004 | int x, y; | 1004 | int x, y; | |
1005 | 1005 | |||
1006 | x = ri->ri_xorigin + ri->ri_font->fontwidth * col; | 1006 | x = ri->ri_xorigin + ri->ri_font->fontwidth * col; | |
1007 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | 1007 | y = ri->ri_yorigin + ri->ri_font->fontheight * row; | |
1008 | zx_fillrect(sc, x, y, ri->ri_font->fontwidth, | 1008 | zx_fillrect(sc, x, y, ri->ri_font->fontwidth, | |
1009 | ri->ri_font->fontheight, bg, ZX_STD_ROP); | 1009 | ri->ri_font->fontheight, bg, ZX_STD_ROP); | |
1010 | return; | 1010 | return; | |
1011 | } | 1011 | } | |
1012 | 1012 | |||
1013 | font = ri->ri_font; | 1013 | font = ri->ri_font; | |
1014 | 1014 | |||
1015 | dp = (volatile u_int32_t *)sc->sc_pixels + | 1015 | dp = (volatile u_int32_t *)sc->sc_pixels + | |
1016 | ((row * font->fontheight + ri->ri_yorigin) << 11) + | 1016 | ((row * font->fontheight + ri->ri_yorigin) << 11) + | |
1017 | (col * font->fontwidth + ri->ri_xorigin); | 1017 | (col * font->fontwidth + ri->ri_xorigin); | |
1018 | fb = (u_int8_t *)font->data + (uc - font->firstchar) * | 1018 | fb = (u_int8_t *)font->data + (uc - font->firstchar) * | |
1019 | ri->ri_fontscale; | 1019 | ri->ri_fontscale; | |
1020 | fs = font->stride; | 1020 | fs = font->stride; | |
1021 | 1021 | |||
1022 | while ((bus_space_read_4(sc->sc_bt, sc->sc_bhzc, zc_csr) & | 1022 | while ((bus_space_read_4(sc->sc_bt, sc->sc_bhzc, zc_csr) & | |
1023 | ZX_CSR_BLT_BUSY) != 0) | 1023 | ZX_CSR_BLT_BUSY) != 0) | |
1024 | ; | 1024 | ; | |
1025 | 1025 | |||
1026 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, ZX_STD_ROP); | 1026 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_rop, ZX_STD_ROP); | |
1027 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_fg, fg); | 1027 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_fg, fg); | |
1028 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_bg, bg); | 1028 | bus_space_write_4(sc->sc_bt, sc->sc_bhzdss0, zd_bg, bg); | |
1029 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_fontmsk, | 1029 | bus_space_write_4(sc->sc_bt, sc->sc_bhzc, zc_fontmsk, | |
1030 | 0xffffffff << (32 - font->fontwidth)); | 1030 | 0xffffffff << (32 - font->fontwidth)); | |
1031 | 1031 | |||
1032 | if (font->fontwidth <= 8) { | 1032 | if (font->fontwidth <= 8) { | |
1033 | for (i = font->fontheight; i != 0; i--, dp += 2048) { | 1033 | for (i = font->fontheight; i != 0; i--, dp += 2048) { | |
1034 | *dp = *fb << 24; | 1034 | *dp = *fb << 24; | |
1035 | fb += fs; | 1035 | fb += fs; | |
1036 | } | 1036 | } | |
1037 | } else { | 1037 | } else { | |
1038 | for (i = font->fontheight; i != 0; i--, dp += 2048) { | 1038 | for (i = font->fontheight; i != 0; i--, dp += 2048) { | |
1039 | *dp = *((u_int16_t *)fb) << 16; | 1039 | *dp = *((u_int16_t *)fb) << 16; | |
1040 | fb += fs; | 1040 | fb += fs; | |
1041 | } | 1041 | } | |
1042 | } | 1042 | } | |
1043 | 1043 | |||
1044 | if (ul) { | 1044 | if (ul) { | |
1045 | dp -= 4096; | 1045 | dp -= 4096; | |
1046 | *dp = 0xffffffff; | 1046 | *dp = 0xffffffff; | |
1047 | } | 1047 | } | |
1048 | } | 1048 | } | |
1049 | 1049 | |||
1050 | #if NWSDISPLAY > 0 | 1050 | #if NWSDISPLAY > 0 | |
1051 | static int | 1051 | static int | |
1052 | zx_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, | 1052 | zx_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, | |
1053 | struct lwp *l) | 1053 | struct lwp *l) | |
1054 | { | 1054 | { | |
1055 | /* we'll probably need to add more stuff here */ | 1055 | /* we'll probably need to add more stuff here */ | |
1056 | struct vcons_data *vd = v; | 1056 | struct vcons_data *vd = v; | |
1057 | struct zx_softc *sc = vd->cookie; | 1057 | struct zx_softc *sc = vd->cookie; | |
1058 | struct wsdisplay_fbinfo *wdf; | 1058 | struct wsdisplay_fbinfo *wdf; | |
1059 | struct rasops_info *ri = &sc->sc_fb.fb_rinfo; | 1059 | struct rasops_info *ri = &sc->sc_fb.fb_rinfo; | |
1060 | struct vcons_screen *ms = sc->vd.active; | 1060 | struct vcons_screen *ms = sc->vd.active; | |
1061 | switch (cmd) { | 1061 | switch (cmd) { | |
1062 | case WSDISPLAYIO_GTYPE: | 1062 | case WSDISPLAYIO_GTYPE: | |
1063 | *(u_int *)data = WSDISPLAY_TYPE_SUNTCX; | 1063 | *(u_int *)data = WSDISPLAY_TYPE_SUNTCX; | |
1064 | return 0; | 1064 | return 0; | |
1065 | case WSDISPLAYIO_GINFO: | 1065 | case WSDISPLAYIO_GINFO: | |
1066 | wdf = (void *)data; | 1066 | wdf = (void *)data; | |
1067 | wdf->height = ri->ri_height; | 1067 | wdf->height = ri->ri_height; | |
1068 | wdf->width = ri->ri_width; | 1068 | wdf->width = ri->ri_width; | |
1069 | wdf->depth = ri->ri_depth; | 1069 | wdf->depth = ri->ri_depth; | |
1070 | wdf->cmsize = 256; | 1070 | wdf->cmsize = 256; | |
1071 | return 0; | 1071 | return 0; | |
1072 | 1072 | |||
1073 | case WSDISPLAYIO_GETCMAP: | 1073 | case WSDISPLAYIO_GETCMAP: | |
1074 | return zx_getcmap(sc, | 1074 | return zx_getcmap(sc, | |
1075 | (struct wsdisplay_cmap *)data); | 1075 | (struct wsdisplay_cmap *)data); | |
1076 | case WSDISPLAYIO_PUTCMAP: | 1076 | case WSDISPLAYIO_PUTCMAP: | |
1077 | return zx_putcmap(sc, | 1077 | return zx_putcmap(sc, | |
1078 | (struct wsdisplay_cmap *)data); | 1078 | (struct wsdisplay_cmap *)data); | |
1079 | 1079 | |||
1080 | case WSDISPLAYIO_SMODE: | 1080 | case WSDISPLAYIO_SMODE: | |
1081 | { | 1081 | { | |
1082 | int new_mode = *(int*)data; | 1082 | int new_mode = *(int*)data; | |
1083 | if (new_mode != sc->sc_mode) | 1083 | if (new_mode != sc->sc_mode) | |
1084 | { | 1084 | { | |
1085 | sc->sc_mode = new_mode; | 1085 | sc->sc_mode = new_mode; | |
1086 | if(new_mode == WSDISPLAYIO_MODE_EMUL) | 1086 | if(new_mode == WSDISPLAYIO_MODE_EMUL) | |
1087 | { | 1087 | { | |
1088 | vcons_redraw_screen(ms); | 1088 | vcons_redraw_screen(ms); | |
1089 | } | 1089 | } | |
1090 | } | 1090 | } | |
1091 | } | 1091 | } | |
1092 | } | 1092 | } | |
1093 | return EPASSTHROUGH; | 1093 | return EPASSTHROUGH; | |
1094 | } | 1094 | } | |
1095 | 1095 | |||
1096 | static paddr_t | 1096 | static paddr_t | |
1097 | zx_mmap(void *v, void *vs, off_t offset, int prot) | 1097 | zx_mmap(void *v, void *vs, off_t offset, int prot) | |
1098 | { | 1098 | { | |
1099 | /* I'm not at all sure this is the right thing to do */ | 1099 | /* I'm not at all sure this is the right thing to do */ | |
1100 | return zxmmap(0, offset, prot); /* assume minor dev 0 for now */ | 1100 | return zxmmap(0, offset, prot); /* assume minor dev 0 for now */ | |
1101 | } | 1101 | } | |
1102 | 1102 | |||
1103 | static int | 1103 | static int | |
1104 | zx_putcmap(struct zx_softc *sc, struct wsdisplay_cmap *cm) | 1104 | zx_putcmap(struct zx_softc *sc, struct wsdisplay_cmap *cm) | |
1105 | { | 1105 | { | |
1106 | u_int index = cm->index; | 1106 | u_int index = cm->index; | |
1107 | u_int count = cm->count; | 1107 | u_int count = cm->count; | |
1108 | int error,i; | 1108 | int error,i; | |
1109 | if (index >= 256 || count > 256 || index + count > 256) | 1109 | if (index >= 256 || count > 256 || index + count > 256) | |
1110 | return EINVAL; | 1110 | return EINVAL; | |
1111 | 1111 | |||
1112 | for (i = 0; i < count; i++) | 1112 | for (i = 0; i < count; i++) | |
1113 | { | 1113 | { | |
1114 | error = copyin(&cm->red[i], | 1114 | error = copyin(&cm->red[i], | |
1115 | &sc->sc_cmap[index + i], 1); | 1115 | &sc->sc_cmap[index + i], 1); | |
1116 | if (error) | 1116 | if (error) | |
1117 | return error; | 1117 | return error; | |
1118 | error = copyin(&cm->green[i], | 1118 | error = copyin(&cm->green[i], | |
1119 | &sc->sc_cmap[index + i + 256], 1); | 1119 | &sc->sc_cmap[index + i + 256], 1); | |
1120 | if (error) | 1120 | if (error) | |
1121 | return error; | 1121 | return error; | |
1122 | error = copyin(&cm->blue[i], | 1122 | error = copyin(&cm->blue[i], | |
1123 | &sc->sc_cmap[index + i + 512], 1); | 1123 | &sc->sc_cmap[index + i + 512], 1); | |
1124 | if (error) | 1124 | if (error) | |
1125 | return error; | 1125 | return error; | |
1126 | } | 1126 | } | |
1127 | zx_cmap_put(sc); | 1127 | zx_cmap_put(sc); | |
1128 | 1128 | |||
1129 | return 0; | 1129 | return 0; | |
1130 | } | 1130 | } | |
1131 | 1131 | |||
1132 | static int | 1132 | static int | |
1133 | zx_getcmap(struct zx_softc *sc, struct wsdisplay_cmap *cm) | 1133 | zx_getcmap(struct zx_softc *sc, struct wsdisplay_cmap *cm) | |
1134 | { | 1134 | { | |
1135 | u_int index = cm->index; | 1135 | u_int index = cm->index; | |
1136 | u_int count = cm->count; | 1136 | u_int count = cm->count; | |
1137 | int error,i; | 1137 | int error,i; | |
1138 | 1138 | |||
1139 | if (index >= 256 || count > 256 || index + count > 256) | 1139 | if (index >= 256 || count > 256 || index + count > 256) | |
1140 | return EINVAL; | 1140 | return EINVAL; | |
1141 | 1141 | |||
1142 | for (i = 0; i < count; i++) | 1142 | for (i = 0; i < count; i++) | |
1143 | { | 1143 | { | |
1144 | error = copyout(&sc->sc_cmap[index + i], | 1144 | error = copyout(&sc->sc_cmap[index + i], | |
1145 | &cm->red[i], 1); | 1145 | &cm->red[i], 1); | |
1146 | if (error) | 1146 | if (error) | |
1147 | return error; | 1147 | return error; | |
1148 | error = copyout(&sc->sc_cmap[index + i + 256], | 1148 | error = copyout(&sc->sc_cmap[index + i + 256], | |
1149 | &cm->green[i], 1); | 1149 | &cm->green[i], 1); | |
1150 | if (error) | 1150 | if (error) | |
1151 | return error; | 1151 | return error; | |
1152 | error = copyout(&sc->sc_cmap[index + i + 256], | 1152 | error = copyout(&sc->sc_cmap[index + i + 256], | |
1153 | &cm->blue[i], 1); | 1153 | &cm->blue[i], 1); | |
1154 | if (error) | 1154 | if (error) | |
1155 | return error; | 1155 | return error; | |
1156 | } | 1156 | } | |
1157 | 1157 | |||
1158 | return 0; | 1158 | return 0; | |
1159 | } | 1159 | } | |
1160 | 1160 | |||
1161 | static void | 1161 | static void | |
1162 | zx_init_screen(void *cookie, struct vcons_screen *scr, | 1162 | zx_init_screen(void *cookie, struct vcons_screen *scr, | |
1163 | int existing, long *defattr) | 1163 | int existing, long *defattr) | |
1164 | { | 1164 | { | |
1165 | struct zx_softc *sc = cookie; | 1165 | struct zx_softc *sc = cookie; | |
1166 | struct rasops_info *ri = &scr->scr_ri; | 1166 | struct rasops_info *ri = &scr->scr_ri; | |
1167 | 1167 | |||
1168 | ri->ri_depth = 8; /*sc->sc_fb.fb_type.fb_depth = 32;*/ | 1168 | ri->ri_depth = 8; /*sc->sc_fb.fb_type.fb_depth = 32;*/ | |
1169 | ri->ri_width = sc->sc_width; | 1169 | ri->ri_width = sc->sc_width; | |
1170 | ri->ri_height = sc->sc_height; | 1170 | ri->ri_height = sc->sc_height; | |
1171 | ri->ri_stride = sc->sc_stride; | 1171 | ri->ri_stride = sc->sc_stride; | |
1172 | ri->ri_flg = RI_CENTER; | 1172 | ri->ri_flg = RI_CENTER; | |
1173 | 1173 | |||
1174 | ri->ri_bits = (void *)sc->sc_pixels; | 1174 | ri->ri_bits = (void *)sc->sc_pixels; | |
1175 | 1175 | |||
1176 | rasops_init(ri, sc->sc_height/8, sc->sc_width/8); | 1176 | rasops_init(ri, sc->sc_height/8, sc->sc_width/8); | |
1177 | ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_REVERSE; | 1177 | ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_REVERSE; | |
1178 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, | 1178 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, | |
1179 | sc->sc_width / ri->ri_font->fontwidth); | 1179 | sc->sc_width / ri->ri_font->fontwidth); | |
1180 | 1180 | |||
1181 | ri->ri_hw = scr; | 1181 | ri->ri_hw = scr; | |
1182 | 1182 | |||
1183 | ri->ri_ops.cursor = zx_do_cursor; | 1183 | ri->ri_ops.cursor = zx_do_cursor; | |
1184 | ri->ri_ops.copycols = zx_copycols; | 1184 | ri->ri_ops.copycols = zx_copycols; | |
1185 | ri->ri_ops.copyrows = zx_copyrows; | 1185 | ri->ri_ops.copyrows = zx_copyrows; | |
1186 | ri->ri_ops.erasecols = zx_erasecols; | 1186 | ri->ri_ops.erasecols = zx_erasecols; | |
1187 | ri->ri_ops.eraserows = zx_eraserows; | 1187 | ri->ri_ops.eraserows = zx_eraserows; | |
1188 | ri->ri_ops.putchar = zx_putchar; | 1188 | ri->ri_ops.putchar = zx_putchar; | |
1189 | } | 1189 | } | |
1190 | 1190 | |||
1191 | #endif /* NWSDISPLAY > 0 */ | 1191 | #endif /* NWSDISPLAY > 0 */ |