| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: genfb.c,v 1.20 2009/02/16 22:24:40 jmcneill Exp $ */ | | 1 | /* $NetBSD: genfb.c,v 1.21 2009/02/17 02:19:33 jmcneill 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. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
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: genfb.c,v 1.20 2009/02/16 22:24:40 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.21 2009/02/17 02:19:33 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/systm.h> | | 33 | #include <sys/systm.h> |
34 | #include <sys/kernel.h> | | 34 | #include <sys/kernel.h> |
35 | #include <sys/device.h> | | 35 | #include <sys/device.h> |
36 | #include <sys/proc.h> | | 36 | #include <sys/proc.h> |
37 | #include <sys/mutex.h> | | 37 | #include <sys/mutex.h> |
38 | #include <sys/ioctl.h> | | 38 | #include <sys/ioctl.h> |
39 | #include <sys/kernel.h> | | 39 | #include <sys/kernel.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/malloc.h> | | 41 | #include <sys/malloc.h> |
42 | | | 42 | |
43 | #include <dev/wscons/wsconsio.h> | | 43 | #include <dev/wscons/wsconsio.h> |
| @@ -134,80 +134,90 @@ genfb_init(struct genfb_softc *sc) | | | @@ -134,80 +134,90 @@ genfb_init(struct genfb_softc *sc) |
134 | sc->sc_cmcb = NULL; | | 134 | sc->sc_cmcb = NULL; |
135 | if (prop_dictionary_get_uint64(dict, "cmap_callback", &cmap_cb)) { | | 135 | if (prop_dictionary_get_uint64(dict, "cmap_callback", &cmap_cb)) { |
136 | if (cmap_cb != 0) | | 136 | if (cmap_cb != 0) |
137 | sc->sc_cmcb = (void *)(vaddr_t)cmap_cb; | | 137 | sc->sc_cmcb = (void *)(vaddr_t)cmap_cb; |
138 | } | | 138 | } |
139 | } | | 139 | } |
140 | | | 140 | |
141 | int | | 141 | int |
142 | genfb_attach(struct genfb_softc *sc, struct genfb_ops *ops) | | 142 | genfb_attach(struct genfb_softc *sc, struct genfb_ops *ops) |
143 | { | | 143 | { |
144 | struct wsemuldisplaydev_attach_args aa; | | 144 | struct wsemuldisplaydev_attach_args aa; |
145 | prop_dictionary_t dict; | | 145 | prop_dictionary_t dict; |
146 | struct rasops_info *ri; | | 146 | struct rasops_info *ri; |
| | | 147 | uint16_t crow; |
147 | long defattr; | | 148 | long defattr; |
148 | int i, j; | | 149 | int i, j; |
149 | bool console; | | 150 | bool console; |
150 | | | 151 | |
151 | dict = device_properties(&sc->sc_dev); | | 152 | dict = device_properties(&sc->sc_dev); |
152 | prop_dictionary_get_bool(dict, "is_console", &console); | | 153 | prop_dictionary_get_bool(dict, "is_console", &console); |
153 | | | 154 | |
| | | 155 | if (prop_dictionary_get_uint16(dict, "cursor-row", &crow) == false) |
| | | 156 | crow = 0; |
| | | 157 | if (prop_dictionary_get_bool(dict, "clear-screen", &sc->sc_want_clear) |
| | | 158 | == false) |
| | | 159 | sc->sc_want_clear = true; |
| | | 160 | |
154 | /* do not attach when we're not console */ | | 161 | /* do not attach when we're not console */ |
155 | if (!console) { | | 162 | if (!console) { |
156 | aprint_normal_dev(&sc->sc_dev, "no console, unable to continue\n"); | | 163 | aprint_normal_dev(&sc->sc_dev, "no console, unable to continue\n"); |
157 | return -1; | | 164 | return -1; |
158 | } | | 165 | } |
159 | | | 166 | |
160 | aprint_verbose_dev(&sc->sc_dev, "framebuffer at %p, size %dx%d, depth %d, " | | 167 | aprint_verbose_dev(&sc->sc_dev, "framebuffer at %p, size %dx%d, depth %d, " |
161 | "stride %d\n", sc->sc_fbaddr, | | 168 | "stride %d\n", sc->sc_fbaddr, |
162 | sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride); | | 169 | sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride); |
163 | | | 170 | |
164 | sc->sc_defaultscreen_descr = (struct wsscreen_descr){ | | 171 | sc->sc_defaultscreen_descr = (struct wsscreen_descr){ |
165 | "default", | | 172 | "default", |
166 | 0, 0, | | 173 | 0, 0, |
167 | NULL, | | 174 | NULL, |
168 | 8, 16, | | 175 | 8, 16, |
169 | WSSCREEN_WSCOLORS | WSSCREEN_HILIT, | | 176 | WSSCREEN_WSCOLORS | WSSCREEN_HILIT, |
170 | NULL | | 177 | NULL |
171 | }; | | 178 | }; |
172 | sc->sc_screens[0] = &sc->sc_defaultscreen_descr; | | 179 | sc->sc_screens[0] = &sc->sc_defaultscreen_descr; |
173 | sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; | | 180 | sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; |
174 | memcpy(&sc->sc_ops, ops, sizeof(struct genfb_ops)); | | 181 | memcpy(&sc->sc_ops, ops, sizeof(struct genfb_ops)); |
175 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; | | 182 | sc->sc_mode = WSDISPLAYIO_MODE_EMUL; |
176 | | | 183 | |
177 | sc->sc_shadowfb = malloc(sc->sc_fbsize, M_DEVBUF, M_WAITOK); | | 184 | sc->sc_shadowfb = malloc(sc->sc_fbsize, M_DEVBUF, M_WAITOK); |
| | | 185 | if (sc->sc_want_clear == false) |
| | | 186 | memcpy(sc->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize); |
178 | | | 187 | |
179 | vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, | | 188 | vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, |
180 | &genfb_accessops); | | 189 | &genfb_accessops); |
181 | sc->vd.init_screen = genfb_init_screen; | | 190 | sc->vd.init_screen = genfb_init_screen; |
182 | | | 191 | |
183 | /* Do not print anything between this point and the screen | | 192 | /* Do not print anything between this point and the screen |
184 | * clear operation below. Otherwise it will be lost. */ | | 193 | * clear operation below. Otherwise it will be lost. */ |
185 | | | 194 | |
186 | ri = &sc->sc_console_screen.scr_ri; | | 195 | ri = &sc->sc_console_screen.scr_ri; |
187 | | | 196 | |
188 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, | | 197 | vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, |
189 | &defattr); | | 198 | &defattr); |
190 | sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | | 199 | sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; |
191 | | | 200 | |
192 | sc->sc_defaultscreen_descr.textops = &ri->ri_ops; | | 201 | sc->sc_defaultscreen_descr.textops = &ri->ri_ops; |
193 | sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; | | 202 | sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; |
194 | sc->sc_defaultscreen_descr.nrows = ri->ri_rows; | | 203 | sc->sc_defaultscreen_descr.nrows = ri->ri_rows; |
195 | sc->sc_defaultscreen_descr.ncols = ri->ri_cols; | | 204 | sc->sc_defaultscreen_descr.ncols = ri->ri_cols; |
196 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, | | 205 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, crow, |
197 | defattr); | | 206 | defattr); |
198 | | | 207 | |
199 | /* Clear the whole screen to bring it to a known state. */ | | 208 | /* Clear the whole screen to bring it to a known state. */ |
200 | (*ri->ri_ops.eraserows)(ri, 0, ri->ri_rows, defattr); | | 209 | if (sc->sc_want_clear) |
| | | 210 | (*ri->ri_ops.eraserows)(ri, 0, ri->ri_rows, defattr); |
201 | | | 211 | |
202 | j = 0; | | 212 | j = 0; |
203 | for (i = 0; i < (1 << sc->sc_depth); i++) { | | 213 | for (i = 0; i < (1 << sc->sc_depth); i++) { |
204 | | | 214 | |
205 | sc->sc_cmap_red[i] = rasops_cmap[j]; | | 215 | sc->sc_cmap_red[i] = rasops_cmap[j]; |
206 | sc->sc_cmap_green[i] = rasops_cmap[j + 1]; | | 216 | sc->sc_cmap_green[i] = rasops_cmap[j + 1]; |
207 | sc->sc_cmap_blue[i] = rasops_cmap[j + 2]; | | 217 | sc->sc_cmap_blue[i] = rasops_cmap[j + 2]; |
208 | genfb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1], | | 218 | genfb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1], |
209 | rasops_cmap[j + 2]); | | 219 | rasops_cmap[j + 2]); |
210 | j += 3; | | 220 | j += 3; |
211 | } | | 221 | } |
212 | | | 222 | |
213 | if (genfb_softc == NULL) | | 223 | if (genfb_softc == NULL) |
| @@ -295,36 +305,38 @@ genfb_mmap(void *v, void *vs, off_t offs | | | @@ -295,36 +305,38 @@ genfb_mmap(void *v, void *vs, off_t offs |
295 | } | | 305 | } |
296 | | | 306 | |
297 | static void | | 307 | static void |
298 | genfb_init_screen(void *cookie, struct vcons_screen *scr, | | 308 | genfb_init_screen(void *cookie, struct vcons_screen *scr, |
299 | int existing, long *defattr) | | 309 | int existing, long *defattr) |
300 | { | | 310 | { |
301 | struct genfb_softc *sc = cookie; | | 311 | struct genfb_softc *sc = cookie; |
302 | struct rasops_info *ri = &scr->scr_ri; | | 312 | struct rasops_info *ri = &scr->scr_ri; |
303 | | | 313 | |
304 | ri->ri_depth = sc->sc_depth; | | 314 | ri->ri_depth = sc->sc_depth; |
305 | ri->ri_width = sc->sc_width; | | 315 | ri->ri_width = sc->sc_width; |
306 | ri->ri_height = sc->sc_height; | | 316 | ri->ri_height = sc->sc_height; |
307 | ri->ri_stride = sc->sc_stride; | | 317 | ri->ri_stride = sc->sc_stride; |
308 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; | | 318 | ri->ri_flg = RI_CENTER; |
| | | 319 | if (sc->sc_want_clear) |
| | | 320 | ri->ri_flg |= RI_FULLCLEAR; |
309 | | | 321 | |
310 | if (sc->sc_shadowfb != NULL) { | | 322 | if (sc->sc_shadowfb != NULL) { |
311 | | | 323 | |
312 | ri->ri_hwbits = (char *)sc->sc_fbaddr; | | 324 | ri->ri_hwbits = (char *)sc->sc_fbaddr; |
313 | ri->ri_bits = (char *)sc->sc_shadowfb; | | 325 | ri->ri_bits = (char *)sc->sc_shadowfb; |
314 | } else | | 326 | } else |
315 | ri->ri_bits = (char *)sc->sc_fbaddr; | | 327 | ri->ri_bits = (char *)sc->sc_fbaddr; |
316 | | | 328 | |
317 | if (existing) { | | 329 | if (existing && sc->sc_want_clear) { |
318 | ri->ri_flg |= RI_CLEAR; | | 330 | ri->ri_flg |= RI_CLEAR; |
319 | } | | 331 | } |
320 | | | 332 | |
321 | rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); | | 333 | rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); |
322 | ri->ri_caps = WSSCREEN_WSCOLORS; | | 334 | ri->ri_caps = WSSCREEN_WSCOLORS; |
323 | | | 335 | |
324 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, | | 336 | rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, |
325 | sc->sc_width / ri->ri_font->fontwidth); | | 337 | sc->sc_width / ri->ri_font->fontwidth); |
326 | | | 338 | |
327 | ri->ri_hw = scr; | | 339 | ri->ri_hw = scr; |
328 | } | | 340 | } |
329 | | | 341 | |
330 | static int | | 342 | static int |