Sun Jul 5 09:55:08 2020 UTC ()
Adapt to proplib api changes


(martin)
diff -r1.64 -r1.65 src/sys/arch/sparc64/dev/ffb.c

cvs diff -r1.64 -r1.65 src/sys/arch/sparc64/dev/ffb.c (switch to unified diff)

--- src/sys/arch/sparc64/dev/ffb.c 2019/12/22 23:23:31 1.64
+++ src/sys/arch/sparc64/dev/ffb.c 2020/07/05 09:55:07 1.65
@@ -1,1308 +1,1308 @@ @@ -1,1308 +1,1308 @@
1/* $NetBSD: ffb.c,v 1.64 2019/12/22 23:23:31 thorpej Exp $ */ 1/* $NetBSD: ffb.c,v 1.65 2020/07/05 09:55:07 martin Exp $ */
2/* $OpenBSD: creator.c,v 1.20 2002/07/30 19:48:15 jason Exp $ */ 2/* $OpenBSD: creator.c,v 1.20 2002/07/30 19:48:15 jason Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2002 Jason L. Wright (jason@thought.net) 5 * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jason L. Wright 18 * This product includes software developed by Jason L. Wright
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE. 32 * POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.64 2019/12/22 23:23:31 thorpej Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.65 2020/07/05 09:55:07 martin Exp $");
37 37
38#include <sys/types.h> 38#include <sys/types.h>
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/kernel.h> 41#include <sys/kernel.h>
42#include <sys/device.h> 42#include <sys/device.h>
43#include <sys/conf.h> 43#include <sys/conf.h>
44#include <sys/ioctl.h> 44#include <sys/ioctl.h>
45#include <sys/malloc.h> 45#include <sys/malloc.h>
46#include <sys/mman.h> 46#include <sys/mman.h>
47 47
48#include <sys/bus.h> 48#include <sys/bus.h>
49#include <machine/autoconf.h> 49#include <machine/autoconf.h>
50#include <machine/openfirm.h> 50#include <machine/openfirm.h>
51#include <machine/vmparam.h> 51#include <machine/vmparam.h>
52 52
53#include <dev/wscons/wsconsio.h> 53#include <dev/wscons/wsconsio.h>
54#include <dev/sun/fbio.h> 54#include <dev/sun/fbio.h>
55#include <dev/sun/fbvar.h> 55#include <dev/sun/fbvar.h>
56 56
57#include <dev/wsfont/wsfont.h> 57#include <dev/wsfont/wsfont.h>
58#include <dev/wscons/wsdisplay_vconsvar.h> 58#include <dev/wscons/wsdisplay_vconsvar.h>
59 59
60#include <prop/proplib.h> 60#include <prop/proplib.h>
61 61
62#include <dev/i2c/i2cvar.h> 62#include <dev/i2c/i2cvar.h>
63#include <dev/i2c/i2c_bitbang.h> 63#include <dev/i2c/i2c_bitbang.h>
64#include <dev/i2c/ddcvar.h> 64#include <dev/i2c/ddcvar.h>
65 65
66#include <sparc64/dev/ffbreg.h> 66#include <sparc64/dev/ffbreg.h>
67#include <sparc64/dev/ffbvar.h> 67#include <sparc64/dev/ffbvar.h>
68 68
69#include "opt_wsdisplay_compat.h" 69#include "opt_wsdisplay_compat.h"
70#include "opt_ffb.h" 70#include "opt_ffb.h"
71 71
72#ifndef WS_DEFAULT_BG 72#ifndef WS_DEFAULT_BG
73/* Sun -> background should be white */ 73/* Sun -> background should be white */
74#define WS_DEFAULT_BG 0xf 74#define WS_DEFAULT_BG 0xf
75#endif 75#endif
76 76
77#ifdef FFB_SYNC 77#ifdef FFB_SYNC
78#define SYNC ffb_ras_wait(sc) 78#define SYNC ffb_ras_wait(sc)
79#else 79#else
80#define SYNC 80#define SYNC
81#endif 81#endif
82 82
83/* Debugging */ 83/* Debugging */
84#if !defined FFB_DEBUG 84#if !defined FFB_DEBUG
85#define FFB_DEBUG 0 85#define FFB_DEBUG 0
86#endif 86#endif
87#define DPRINTF(x) if (ffb_debug) printf x 87#define DPRINTF(x) if (ffb_debug) printf x
88/* Patchable */ 88/* Patchable */
89extern int ffb_debug; 89extern int ffb_debug;
90#if FFB_DEBUG > 0 90#if FFB_DEBUG > 0
91int ffb_debug = 1; 91int ffb_debug = 1;
92#else 92#else
93int ffb_debug = 0; 93int ffb_debug = 0;
94#endif 94#endif
95 95
96extern struct cfdriver ffb_cd; 96extern struct cfdriver ffb_cd;
97 97
98struct wsscreen_descr ffb_stdscreen = { 98struct wsscreen_descr ffb_stdscreen = {
99 "sunffb", 99 "sunffb",
100 0, 0, /* will be filled in -- XXX shouldn't, it's global. */ 100 0, 0, /* will be filled in -- XXX shouldn't, it's global. */
101 0, 101 0,
102 0, 0, 102 0, 0,
103 WSSCREEN_REVERSE | WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE | 103 WSSCREEN_REVERSE | WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE |
104 WSSCREEN_RESIZE, 104 WSSCREEN_RESIZE,
105 NULL /* modecookie */ 105 NULL /* modecookie */
106}; 106};
107 107
108const struct wsscreen_descr *ffb_scrlist[] = { 108const struct wsscreen_descr *ffb_scrlist[] = {
109 &ffb_stdscreen, 109 &ffb_stdscreen,
110 /* XXX other formats? */ 110 /* XXX other formats? */
111}; 111};
112 112
113struct wsscreen_list ffb_screenlist = { 113struct wsscreen_list ffb_screenlist = {
114 sizeof(ffb_scrlist) / sizeof(struct wsscreen_descr *), 114 sizeof(ffb_scrlist) / sizeof(struct wsscreen_descr *),
115 ffb_scrlist 115 ffb_scrlist
116}; 116};
117 117
118static struct vcons_screen ffb_console_screen; 118static struct vcons_screen ffb_console_screen;
119 119
120int ffb_ioctl(void *, void *, u_long, void *, int, struct lwp *); 120int ffb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
121static int ffb_blank(struct ffb_softc *, u_long, u_int *); 121static int ffb_blank(struct ffb_softc *, u_long, u_int *);
122paddr_t ffb_mmap(void *, void *, off_t, int); 122paddr_t ffb_mmap(void *, void *, off_t, int);
123void ffb_ras_fifo_wait(struct ffb_softc *, int); 123void ffb_ras_fifo_wait(struct ffb_softc *, int);
124void ffb_ras_wait(struct ffb_softc *); 124void ffb_ras_wait(struct ffb_softc *);
125void ffb_ras_init(struct ffb_softc *); 125void ffb_ras_init(struct ffb_softc *);
126void ffb_ras_copyrows(void *, int, int, int); 126void ffb_ras_copyrows(void *, int, int, int);
127void ffb_ras_erasecols(void *, int, int, int, long int); 127void ffb_ras_erasecols(void *, int, int, int, long int);
128void ffb_ras_eraserows(void *, int, int, long int); 128void ffb_ras_eraserows(void *, int, int, long int);
129void ffb_ras_fill(struct ffb_softc *); 129void ffb_ras_fill(struct ffb_softc *);
130void ffb_ras_invert(struct ffb_softc *); 130void ffb_ras_invert(struct ffb_softc *);
131static void ffb_ras_setfg(struct ffb_softc *, int32_t); 131static void ffb_ras_setfg(struct ffb_softc *, int32_t);
132static void ffb_ras_setbg(struct ffb_softc *, int32_t); 132static void ffb_ras_setbg(struct ffb_softc *, int32_t);
133 133
134void ffb_clearscreen(struct ffb_softc *); 134void ffb_clearscreen(struct ffb_softc *);
135void ffb_init_screen(void *, struct vcons_screen *, int,  135void ffb_init_screen(void *, struct vcons_screen *, int,
136 long *); 136 long *);
137int ffb_allocattr(void *, int, int, int, long *); 137int ffb_allocattr(void *, int, int, int, long *);
138void ffb_putchar_mono(void *, int, int, u_int, long); 138void ffb_putchar_mono(void *, int, int, u_int, long);
139void ffb_putchar_aa(void *, int, int, u_int, long); 139void ffb_putchar_aa(void *, int, int, u_int, long);
140void ffb_cursor(void *, int, int, int); 140void ffb_cursor(void *, int, int, int);
141 141
142/* frame buffer generic driver */  142/* frame buffer generic driver */
143static void ffbfb_unblank(device_t); 143static void ffbfb_unblank(device_t);
144dev_type_open(ffbfb_open); 144dev_type_open(ffbfb_open);
145dev_type_close(ffbfb_close); 145dev_type_close(ffbfb_close);
146dev_type_ioctl(ffbfb_ioctl); 146dev_type_ioctl(ffbfb_ioctl);
147dev_type_mmap(ffbfb_mmap); 147dev_type_mmap(ffbfb_mmap);
148 148
149static struct fbdriver ffb_fbdriver = { 149static struct fbdriver ffb_fbdriver = {
150 ffbfb_unblank, ffbfb_open, ffbfb_close, ffbfb_ioctl, nopoll, 150 ffbfb_unblank, ffbfb_open, ffbfb_close, ffbfb_ioctl, nopoll,
151 ffbfb_mmap, nokqfilter 151 ffbfb_mmap, nokqfilter
152}; 152};
153 153
154struct wsdisplay_accessops ffb_accessops = { 154struct wsdisplay_accessops ffb_accessops = {
155 .ioctl = ffb_ioctl, 155 .ioctl = ffb_ioctl,
156 .mmap = ffb_mmap, 156 .mmap = ffb_mmap,
157}; 157};
158 158
159/* I2C glue */ 159/* I2C glue */
160static int ffb_i2c_send_start(void *, int); 160static int ffb_i2c_send_start(void *, int);
161static int ffb_i2c_send_stop(void *, int); 161static int ffb_i2c_send_stop(void *, int);
162static int ffb_i2c_initiate_xfer(void *, i2c_addr_t, int); 162static int ffb_i2c_initiate_xfer(void *, i2c_addr_t, int);
163static int ffb_i2c_read_byte(void *, uint8_t *, int); 163static int ffb_i2c_read_byte(void *, uint8_t *, int);
164static int ffb_i2c_write_byte(void *, uint8_t, int); 164static int ffb_i2c_write_byte(void *, uint8_t, int);
165 165
166/* I2C bitbang glue */ 166/* I2C bitbang glue */
167static void ffb_i2cbb_set_bits(void *, uint32_t); 167static void ffb_i2cbb_set_bits(void *, uint32_t);
168static void ffb_i2cbb_set_dir(void *, uint32_t); 168static void ffb_i2cbb_set_dir(void *, uint32_t);
169static uint32_t ffb_i2cbb_read(void *); 169static uint32_t ffb_i2cbb_read(void *);
170 170
171static const struct i2c_bitbang_ops ffb_i2cbb_ops = { 171static const struct i2c_bitbang_ops ffb_i2cbb_ops = {
172 ffb_i2cbb_set_bits, 172 ffb_i2cbb_set_bits,
173 ffb_i2cbb_set_dir, 173 ffb_i2cbb_set_dir,
174 ffb_i2cbb_read, 174 ffb_i2cbb_read,
175 { 175 {
176 FFB_DAC_CFG_MPDATA_SDA, 176 FFB_DAC_CFG_MPDATA_SDA,
177 FFB_DAC_CFG_MPDATA_SCL, 177 FFB_DAC_CFG_MPDATA_SCL,
178 0, 178 0,
179 0 179 0
180 } 180 }
181}; 181};
182 182
183void ffb_attach_i2c(struct ffb_softc *); 183void ffb_attach_i2c(struct ffb_softc *);
184 184
185/* Video mode setting */ 185/* Video mode setting */
186int ffb_tgc_disable(struct ffb_softc *); 186int ffb_tgc_disable(struct ffb_softc *);
187void ffb_get_pclk(int, uint32_t *, int *); 187void ffb_get_pclk(int, uint32_t *, int *);
188int ffb_set_vmode(struct ffb_softc *, struct videomode *, int, int *, int *); 188int ffb_set_vmode(struct ffb_softc *, struct videomode *, int, int *, int *);
189 189
190 190
191void 191void
192ffb_attach(device_t self) 192ffb_attach(device_t self)
193{ 193{
194 struct ffb_softc *sc = device_private(self); 194 struct ffb_softc *sc = device_private(self);
195 struct wsemuldisplaydev_attach_args waa; 195 struct wsemuldisplaydev_attach_args waa;
196 struct rasops_info *ri; 196 struct rasops_info *ri;
197 long defattr; 197 long defattr;
198 const char *model, *out_dev; 198 const char *model, *out_dev;
199 int btype; 199 int btype;
200 uint32_t dac; 200 uint32_t dac;
201 int maxrow; 201 int maxrow;
202 u_int blank = WSDISPLAYIO_VIDEO_ON; 202 u_int blank = WSDISPLAYIO_VIDEO_ON;
203 char buf[6+1]; 203 char buf[6+1];
204 int i, try_edid; 204 int i, try_edid;
205 prop_data_t data; 205 prop_data_t data;
206 206
207 printf(":"); 207 printf(":");
208  208
209 if (sc->sc_type == FFB_CREATOR) { 209 if (sc->sc_type == FFB_CREATOR) {
210 btype = prom_getpropint(sc->sc_node, "board_type", 0); 210 btype = prom_getpropint(sc->sc_node, "board_type", 0);
211 if ((btype & 7) == 3) 211 if ((btype & 7) == 3)
212 printf(" Creator3D"); 212 printf(" Creator3D");
213 else 213 else
214 printf(" Creator"); 214 printf(" Creator");
215 } else { 215 } else {
216 printf(" Elite3D"); 216 printf(" Elite3D");
217 btype = 0; 217 btype = 0;
218 } 218 }
219 219
220 model = prom_getpropstring(sc->sc_node, "model"); 220 model = prom_getpropstring(sc->sc_node, "model");
221 if (model == NULL || strlen(model) == 0) 221 if (model == NULL || strlen(model) == 0)
222 model = "unknown"; 222 model = "unknown";
223 223
224 sc->sc_depth = 24; 224 sc->sc_depth = 24;
225 sc->sc_linebytes = 8192; 225 sc->sc_linebytes = 8192;
226 /* We might alter these during EDID mode setting */ 226 /* We might alter these during EDID mode setting */
227 sc->sc_height = prom_getpropint(sc->sc_node, "height", 0); 227 sc->sc_height = prom_getpropint(sc->sc_node, "height", 0);
228 sc->sc_width = prom_getpropint(sc->sc_node, "width", 0); 228 sc->sc_width = prom_getpropint(sc->sc_node, "width", 0);
229  229
230 sc->sc_locked = 0; 230 sc->sc_locked = 0;
231 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 231 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
232  232
233 maxrow = (prom_getoption("screen-#rows", buf, sizeof buf) != 0) 233 maxrow = (prom_getoption("screen-#rows", buf, sizeof buf) != 0)
234 ? strtoul(buf, NULL, 10) 234 ? strtoul(buf, NULL, 10)
235 : 34; 235 : 34;
236 236
237 /* collect DAC version, as Elite3D cursor enable bit is reversed */ 237 /* collect DAC version, as Elite3D cursor enable bit is reversed */
238 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_DEVID); 238 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_DEVID);
239 dac = DAC_READ(sc, FFB_DAC_VALUE); 239 dac = DAC_READ(sc, FFB_DAC_VALUE);
240 sc->sc_dacrev = (dac >> 28) & 0xf; 240 sc->sc_dacrev = (dac >> 28) & 0xf;
241 241
242 if (sc->sc_type == FFB_AFB) { 242 if (sc->sc_type == FFB_AFB) {
243 sc->sc_dacrev = 10; 243 sc->sc_dacrev = 10;
244 sc->sc_needredraw = 0; 244 sc->sc_needredraw = 0;
245 } else { 245 } else {
246 /* see what kind of DAC we have */ 246 /* see what kind of DAC we have */
247 int pnum = (dac & 0x0ffff000) >> 12; 247 int pnum = (dac & 0x0ffff000) >> 12;
248 if (pnum == 0x236e) { 248 if (pnum == 0x236e) {
249 sc->sc_needredraw = 0; 249 sc->sc_needredraw = 0;
250 } else { 250 } else {
251 sc->sc_needredraw = 1; 251 sc->sc_needredraw = 1;
252 } 252 }
253 } 253 }
254 printf(", model %s, dac %u\n", model, sc->sc_dacrev); 254 printf(", model %s, dac %u\n", model, sc->sc_dacrev);
255 if (sc->sc_needredraw)  255 if (sc->sc_needredraw)
256 printf("%s: found old DAC, enabling redraw on unblank\n",  256 printf("%s: found old DAC, enabling redraw on unblank\n",
257 device_xname(sc->sc_dev)); 257 device_xname(sc->sc_dev));
258 258
259 /* Check if a console resolution "<device>:r<res>" is set. */ 259 /* Check if a console resolution "<device>:r<res>" is set. */
260 if (sc->sc_console) { 260 if (sc->sc_console) {
261 out_dev = prom_getpropstring(sc->sc_node, "output-device"); 261 out_dev = prom_getpropstring(sc->sc_node, "output-device");
262 if (out_dev != NULL && strlen(out_dev) != 0 && 262 if (out_dev != NULL && strlen(out_dev) != 0 &&
263 strstr(out_dev, ":r") != NULL) 263 strstr(out_dev, ":r") != NULL)
264 try_edid = 0; 264 try_edid = 0;
265 else 265 else
266 try_edid = 1; 266 try_edid = 1;
267 } else 267 } else
268 try_edid = 1; 268 try_edid = 1;
269 269
270#if FFB_DEBUG > 0 270#if FFB_DEBUG > 0
271 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_TGC); 271 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_TGC);
272 printf("tgc: %08x\n", DAC_READ(sc, FFB_DAC_VALUE)); 272 printf("tgc: %08x\n", DAC_READ(sc, FFB_DAC_VALUE));
273 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_DAC_CTRL); 273 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_DAC_CTRL);
274 printf("dcl: %08x\n", DAC_READ(sc, FFB_DAC_VALUE)); 274 printf("dcl: %08x\n", DAC_READ(sc, FFB_DAC_VALUE));
275#endif 275#endif
276 ffb_attach_i2c(sc); 276 ffb_attach_i2c(sc);
277 277
278 /* Need to set asynchronous blank during DDC write/read */ 278 /* Need to set asynchronous blank during DDC write/read */
279 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_USR_CTRL); 279 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_USR_CTRL);
280 dac = DAC_READ(sc, FFB_DAC_VALUE); 280 dac = DAC_READ(sc, FFB_DAC_VALUE);
281 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_USR_CTRL); 281 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_USR_CTRL);
282 DAC_WRITE(sc, FFB_DAC_VALUE, dac | FFB_DAC_USR_CTRL_BLANK); 282 DAC_WRITE(sc, FFB_DAC_VALUE, dac | FFB_DAC_USR_CTRL_BLANK);
283 283
284 /* Some monitors don't respond first time */ 284 /* Some monitors don't respond first time */
285 i = 0; 285 i = 0;
286 while (sc->sc_edid_data[1] == 0 && i++ < 3) 286 while (sc->sc_edid_data[1] == 0 && i++ < 3)
287 ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, EDID_DATA_LEN); 287 ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, EDID_DATA_LEN);
288 288
289 /* Remove asynchronous blank */ 289 /* Remove asynchronous blank */
290 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_USR_CTRL); 290 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_USR_CTRL);
291 DAC_WRITE(sc, FFB_DAC_VALUE, dac); 291 DAC_WRITE(sc, FFB_DAC_VALUE, dac);
292 292
293 if (edid_parse(&sc->sc_edid_data[0], &sc->sc_edid_info) != -1) { 293 if (edid_parse(&sc->sc_edid_data[0], &sc->sc_edid_info) != -1) {
294 sort_modes(sc->sc_edid_info.edid_modes, 294 sort_modes(sc->sc_edid_info.edid_modes,
295 &sc->sc_edid_info.edid_preferred_mode, 295 &sc->sc_edid_info.edid_preferred_mode,
296 sc->sc_edid_info.edid_nmodes); 296 sc->sc_edid_info.edid_nmodes);
297 DPRINTF(("%s: EDID data:\n ", device_xname(sc->sc_dev))); 297 DPRINTF(("%s: EDID data:\n ", device_xname(sc->sc_dev)));
298 for (i = 0; i < EDID_DATA_LEN; i++) { 298 for (i = 0; i < EDID_DATA_LEN; i++) {
299 if (i && !(i % 32)) 299 if (i && !(i % 32))
300 DPRINTF(("\n ")); 300 DPRINTF(("\n "));
301 if (i && !(i % 4)) 301 if (i && !(i % 4))
302 DPRINTF((" ")); 302 DPRINTF((" "));
303 DPRINTF(("%02x", sc->sc_edid_data[i])); 303 DPRINTF(("%02x", sc->sc_edid_data[i]));
304 } 304 }
305 DPRINTF(("\n")); 305 DPRINTF(("\n"));
306 if (ffb_debug) 306 if (ffb_debug)
307 edid_print(&sc->sc_edid_info); 307 edid_print(&sc->sc_edid_info);
308 308
309 data = prop_data_create_data(sc->sc_edid_data, EDID_DATA_LEN); 309 data = prop_data_create_copy(sc->sc_edid_data, EDID_DATA_LEN);
310 prop_dictionary_set(device_properties(self), "EDID", data); 310 prop_dictionary_set(device_properties(self), "EDID", data);
311 prop_object_release(data); 311 prop_object_release(data);
312 312
313 if (try_edid) 313 if (try_edid)
314 for (i = 0; i < sc->sc_edid_info.edid_nmodes; i++) { 314 for (i = 0; i < sc->sc_edid_info.edid_nmodes; i++) {
315 if (ffb_set_vmode(sc, 315 if (ffb_set_vmode(sc,
316 &(sc->sc_edid_info.edid_modes[i]), btype, 316 &(sc->sc_edid_info.edid_modes[i]), btype,
317 &(sc->sc_width), &(sc->sc_height))) 317 &(sc->sc_width), &(sc->sc_height)))
318 break; 318 break;
319 } 319 }
320 } else { 320 } else {
321 DPRINTF(("%s: No EDID data.\n", device_xname(sc->sc_dev))); 321 DPRINTF(("%s: No EDID data.\n", device_xname(sc->sc_dev)));
322 } 322 }
323  323
324 ffb_ras_init(sc); 324 ffb_ras_init(sc);
325 325
326 ffb_blank(sc, WSDISPLAYIO_SVIDEO, &blank); 326 ffb_blank(sc, WSDISPLAYIO_SVIDEO, &blank);
327 327
328 sc->sc_accel = ((device_cfdata(sc->sc_dev)->cf_flags & 328 sc->sc_accel = ((device_cfdata(sc->sc_dev)->cf_flags &
329 FFB_CFFLAG_NOACCEL) == 0); 329 FFB_CFFLAG_NOACCEL) == 0);
330  330
331 wsfont_init(); 331 wsfont_init();
332 332
333 vcons_init(&sc->vd, sc, &ffb_stdscreen, &ffb_accessops); 333 vcons_init(&sc->vd, sc, &ffb_stdscreen, &ffb_accessops);
334 sc->vd.init_screen = ffb_init_screen; 334 sc->vd.init_screen = ffb_init_screen;
335 ri = &ffb_console_screen.scr_ri; 335 ri = &ffb_console_screen.scr_ri;
336 336
337 /* we mess with ffb_console_screen only once */ 337 /* we mess with ffb_console_screen only once */
338 if (sc->sc_console) { 338 if (sc->sc_console) {
339 ffb_console_screen.scr_flags = VCONS_SCREEN_IS_STATIC; 339 ffb_console_screen.scr_flags = VCONS_SCREEN_IS_STATIC;
340 vcons_init_screen(&sc->vd, &ffb_console_screen, 1, &defattr); 340 vcons_init_screen(&sc->vd, &ffb_console_screen, 1, &defattr);
341 SCREEN_VISIBLE((&ffb_console_screen)); 341 SCREEN_VISIBLE((&ffb_console_screen));
342 /*  342 /*
343 * XXX we shouldn't use a global variable for the console 343 * XXX we shouldn't use a global variable for the console
344 * screen 344 * screen
345 */ 345 */
346 sc->vd.active = &ffb_console_screen; 346 sc->vd.active = &ffb_console_screen;
347 } else { 347 } else {
348 if (ffb_console_screen.scr_ri.ri_rows == 0) { 348 if (ffb_console_screen.scr_ri.ri_rows == 0) {
349 /* do some minimal setup to avoid weirdnesses later */ 349 /* do some minimal setup to avoid weirdnesses later */
350 vcons_init_screen(&sc->vd, &ffb_console_screen, 1, &defattr); 350 vcons_init_screen(&sc->vd, &ffb_console_screen, 1, &defattr);
351 } else 351 } else
352 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); 352 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
353 } 353 }
354 354
355 ffb_stdscreen.nrows = ri->ri_rows; 355 ffb_stdscreen.nrows = ri->ri_rows;
356 ffb_stdscreen.ncols = ri->ri_cols; 356 ffb_stdscreen.ncols = ri->ri_cols;
357 ffb_stdscreen.textops = &ri->ri_ops; 357 ffb_stdscreen.textops = &ri->ri_ops;
358  358
359 sc->sc_fb.fb_driver = &ffb_fbdriver; 359 sc->sc_fb.fb_driver = &ffb_fbdriver;
360 sc->sc_fb.fb_type.fb_cmsize = 0; 360 sc->sc_fb.fb_type.fb_cmsize = 0;
361 sc->sc_fb.fb_type.fb_size = maxrow * sc->sc_linebytes; 361 sc->sc_fb.fb_type.fb_size = maxrow * sc->sc_linebytes;
362 sc->sc_fb.fb_type.fb_type = FBTYPE_CREATOR; 362 sc->sc_fb.fb_type.fb_type = FBTYPE_CREATOR;
363 sc->sc_fb.fb_type.fb_width = sc->sc_width; 363 sc->sc_fb.fb_type.fb_width = sc->sc_width;
364 sc->sc_fb.fb_type.fb_depth = sc->sc_depth; 364 sc->sc_fb.fb_type.fb_depth = sc->sc_depth;
365 sc->sc_fb.fb_type.fb_height = sc->sc_height; 365 sc->sc_fb.fb_type.fb_height = sc->sc_height;
366 sc->sc_fb.fb_device = sc->sc_dev; 366 sc->sc_fb.fb_device = sc->sc_dev;
367 fb_attach(&sc->sc_fb, sc->sc_console); 367 fb_attach(&sc->sc_fb, sc->sc_console);
368 368
369 ffb_clearscreen(sc); 369 ffb_clearscreen(sc);
370 370
371 if (sc->sc_console) { 371 if (sc->sc_console) {
372 wsdisplay_cnattach(&ffb_stdscreen, ri, 0, 0, defattr); 372 wsdisplay_cnattach(&ffb_stdscreen, ri, 0, 0, defattr);
373 vcons_replay_msgbuf(&ffb_console_screen); 373 vcons_replay_msgbuf(&ffb_console_screen);
374 } 374 }
375  375
376 waa.console = sc->sc_console; 376 waa.console = sc->sc_console;
377 waa.scrdata = &ffb_screenlist; 377 waa.scrdata = &ffb_screenlist;
378 waa.accessops = &ffb_accessops; 378 waa.accessops = &ffb_accessops;
379 waa.accesscookie = &sc->vd; 379 waa.accesscookie = &sc->vd;
380 config_found(sc->sc_dev, &waa, wsemuldisplaydevprint); 380 config_found(sc->sc_dev, &waa, wsemuldisplaydevprint);
381} 381}
382 382
383void 383void
384ffb_attach_i2c(struct ffb_softc *sc) 384ffb_attach_i2c(struct ffb_softc *sc)
385{ 385{
386 386
387 /* Fill in the i2c tag */ 387 /* Fill in the i2c tag */
388 iic_tag_init(&sc->sc_i2c); 388 iic_tag_init(&sc->sc_i2c);
389 sc->sc_i2c.ic_cookie = sc; 389 sc->sc_i2c.ic_cookie = sc;
390 sc->sc_i2c.ic_send_start = ffb_i2c_send_start; 390 sc->sc_i2c.ic_send_start = ffb_i2c_send_start;
391 sc->sc_i2c.ic_send_stop = ffb_i2c_send_stop; 391 sc->sc_i2c.ic_send_stop = ffb_i2c_send_stop;
392 sc->sc_i2c.ic_initiate_xfer = ffb_i2c_initiate_xfer; 392 sc->sc_i2c.ic_initiate_xfer = ffb_i2c_initiate_xfer;
393 sc->sc_i2c.ic_read_byte = ffb_i2c_read_byte; 393 sc->sc_i2c.ic_read_byte = ffb_i2c_read_byte;
394 sc->sc_i2c.ic_write_byte = ffb_i2c_write_byte; 394 sc->sc_i2c.ic_write_byte = ffb_i2c_write_byte;
395} 395}
396 396
397int 397int
398ffb_ioctl(void *v, void *vs, u_long cmd, void *data, int flags, struct lwp *l) 398ffb_ioctl(void *v, void *vs, u_long cmd, void *data, int flags, struct lwp *l)
399{ 399{
400 struct vcons_data *vd = v; 400 struct vcons_data *vd = v;
401 struct ffb_softc *sc = vd->cookie; 401 struct ffb_softc *sc = vd->cookie;
402 struct wsdisplay_fbinfo *wdf; 402 struct wsdisplay_fbinfo *wdf;
403 struct vcons_screen *ms = vd->active; 403 struct vcons_screen *ms = vd->active;
404 404
405 DPRINTF(("ffb_ioctl: %s cmd _IO%s%s('%c', %lu)\n", 405 DPRINTF(("ffb_ioctl: %s cmd _IO%s%s('%c', %lu)\n",
406 device_xname(sc->sc_dev), 406 device_xname(sc->sc_dev),
407 (cmd & IOC_IN) ? "W" : "", (cmd & IOC_OUT) ? "R" : "", 407 (cmd & IOC_IN) ? "W" : "", (cmd & IOC_OUT) ? "R" : "",
408 (char)IOCGROUP(cmd), cmd & 0xff)); 408 (char)IOCGROUP(cmd), cmd & 0xff));
409 409
410 switch (cmd) { 410 switch (cmd) {
411 case FBIOGTYPE: 411 case FBIOGTYPE:
412 *(struct fbtype *)data = sc->sc_fb.fb_type; 412 *(struct fbtype *)data = sc->sc_fb.fb_type;
413 break; 413 break;
414 case FBIOGATTR: 414 case FBIOGATTR:
415#define fba ((struct fbgattr *)data) 415#define fba ((struct fbgattr *)data)
416 fba->real_type = sc->sc_fb.fb_type.fb_type; 416 fba->real_type = sc->sc_fb.fb_type.fb_type;
417 fba->owner = 0; /* XXX ??? */ 417 fba->owner = 0; /* XXX ??? */
418 fba->fbtype = sc->sc_fb.fb_type; 418 fba->fbtype = sc->sc_fb.fb_type;
419 fba->sattr.flags = 0; 419 fba->sattr.flags = 0;
420 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; 420 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
421 fba->sattr.dev_specific[0] = -1; 421 fba->sattr.dev_specific[0] = -1;
422 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; 422 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
423 fba->emu_types[1] = -1; 423 fba->emu_types[1] = -1;
424#undef fba 424#undef fba
425 break; 425 break;
426 426
427 case FBIOGETCMAP: 427 case FBIOGETCMAP:
428 case FBIOPUTCMAP: 428 case FBIOPUTCMAP:
429 return EIO; 429 return EIO;
430 430
431 case FBIOGVIDEO: 431 case FBIOGVIDEO:
432 case FBIOSVIDEO: 432 case FBIOSVIDEO:
433 return ffb_blank(sc, cmd == FBIOGVIDEO? 433 return ffb_blank(sc, cmd == FBIOGVIDEO?
434 WSDISPLAYIO_GVIDEO : WSDISPLAYIO_SVIDEO, 434 WSDISPLAYIO_GVIDEO : WSDISPLAYIO_SVIDEO,
435 (u_int *)data); 435 (u_int *)data);
436 break; 436 break;
437 case FBIOGCURSOR: 437 case FBIOGCURSOR:
438 case FBIOSCURSOR: 438 case FBIOSCURSOR:
439 /* the console driver is not using the hardware cursor */ 439 /* the console driver is not using the hardware cursor */
440 break; 440 break;
441 case FBIOGCURPOS: 441 case FBIOGCURPOS:
442 printf("%s: FBIOGCURPOS not implemented\n", 442 printf("%s: FBIOGCURPOS not implemented\n",
443 device_xname(sc->sc_dev)); 443 device_xname(sc->sc_dev));
444 return EIO; 444 return EIO;
445 case FBIOSCURPOS: 445 case FBIOSCURPOS:
446 printf("%s: FBIOSCURPOS not implemented\n", 446 printf("%s: FBIOSCURPOS not implemented\n",
447 device_xname(sc->sc_dev)); 447 device_xname(sc->sc_dev));
448 return EIO; 448 return EIO;
449 case FBIOGCURMAX: 449 case FBIOGCURMAX:
450 printf("%s: FBIOGCURMAX not implemented\n", 450 printf("%s: FBIOGCURMAX not implemented\n",
451 device_xname(sc->sc_dev)); 451 device_xname(sc->sc_dev));
452 return EIO; 452 return EIO;
453 453
454 case WSDISPLAYIO_GTYPE: 454 case WSDISPLAYIO_GTYPE:
455 *(u_int *)data = WSDISPLAY_TYPE_SUNFFB; 455 *(u_int *)data = WSDISPLAY_TYPE_SUNFFB;
456 break; 456 break;
457 case WSDISPLAYIO_SMODE: 457 case WSDISPLAYIO_SMODE:
458 {  458 {
459 if (sc->sc_mode != *(u_int *)data) { 459 if (sc->sc_mode != *(u_int *)data) {
460 sc->sc_mode = *(u_int *)data; 460 sc->sc_mode = *(u_int *)data;
461 if ((sc->sc_mode == WSDISPLAYIO_MODE_EMUL) && 461 if ((sc->sc_mode == WSDISPLAYIO_MODE_EMUL) &&
462 (sc->sc_locked == 0)) { 462 (sc->sc_locked == 0)) {
463 ffb_ras_init(sc); 463 ffb_ras_init(sc);
464 vcons_redraw_screen(ms); 464 vcons_redraw_screen(ms);
465 } else { 465 } else {
466 ffb_ras_wait(sc); 466 ffb_ras_wait(sc);
467 } 467 }
468 } 468 }
469 }  469 }
470 break; 470 break;
471 case WSDISPLAYIO_GINFO: 471 case WSDISPLAYIO_GINFO:
472 wdf = (void *)data; 472 wdf = (void *)data;
473 wdf->height = sc->sc_height; 473 wdf->height = sc->sc_height;
474 wdf->width = sc->sc_width; 474 wdf->width = sc->sc_width;
475 wdf->depth = 32; 475 wdf->depth = 32;
476 wdf->cmsize = 256; /* XXX */ 476 wdf->cmsize = 256; /* XXX */
477 break; 477 break;
478#ifdef WSDISPLAYIO_LINEBYTES 478#ifdef WSDISPLAYIO_LINEBYTES
479 case WSDISPLAYIO_LINEBYTES: 479 case WSDISPLAYIO_LINEBYTES:
480 *(u_int *)data = sc->sc_linebytes; 480 *(u_int *)data = sc->sc_linebytes;
481 break; 481 break;
482#endif 482#endif
483 case WSDISPLAYIO_GETCMAP: 483 case WSDISPLAYIO_GETCMAP:
484 break;/* XXX */ 484 break;/* XXX */
485 485
486 case WSDISPLAYIO_PUTCMAP: 486 case WSDISPLAYIO_PUTCMAP:
487 break;/* XXX */ 487 break;/* XXX */
488 488
489 case WSDISPLAYIO_SVIDEO: 489 case WSDISPLAYIO_SVIDEO:
490 case WSDISPLAYIO_GVIDEO: 490 case WSDISPLAYIO_GVIDEO:
491 return(ffb_blank(sc, cmd, (u_int *)data)); 491 return(ffb_blank(sc, cmd, (u_int *)data));
492 break; 492 break;
493  493
494 case WSDISPLAYIO_GCURPOS: 494 case WSDISPLAYIO_GCURPOS:
495 case WSDISPLAYIO_SCURPOS: 495 case WSDISPLAYIO_SCURPOS:
496 case WSDISPLAYIO_GCURMAX: 496 case WSDISPLAYIO_GCURMAX:
497 case WSDISPLAYIO_GCURSOR: 497 case WSDISPLAYIO_GCURSOR:
498 case WSDISPLAYIO_SCURSOR: 498 case WSDISPLAYIO_SCURSOR:
499 return EIO; /* not supported yet */ 499 return EIO; /* not supported yet */
500 break; 500 break;
501  501
502 case WSDISPLAYIO_GET_EDID: { 502 case WSDISPLAYIO_GET_EDID: {
503 struct wsdisplayio_edid_info *d = data; 503 struct wsdisplayio_edid_info *d = data;
504 return wsdisplayio_get_edid(sc->sc_dev, d); 504 return wsdisplayio_get_edid(sc->sc_dev, d);
505 } 505 }
506  506
507 case WSDISPLAYIO_GET_FBINFO: { 507 case WSDISPLAYIO_GET_FBINFO: {
508 struct wsdisplayio_fbinfo *fbi = data; 508 struct wsdisplayio_fbinfo *fbi = data;
509 return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); 509 return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
510 } 510 }
511  511
512 default: 512 default:
513 return EPASSTHROUGH; 513 return EPASSTHROUGH;
514 } 514 }
515 515
516 return (0); 516 return (0);
517} 517}
518 518
519/* blank/unblank the screen */ 519/* blank/unblank the screen */
520static int 520static int
521ffb_blank(struct ffb_softc *sc, u_long cmd, u_int *data) 521ffb_blank(struct ffb_softc *sc, u_long cmd, u_int *data)
522{ 522{
523 struct vcons_screen *ms = sc->vd.active; 523 struct vcons_screen *ms = sc->vd.active;
524 u_int val; 524 u_int val;
525  525
526 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_TGC); 526 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_TGC);
527 val = DAC_READ(sc, FFB_DAC_VALUE); 527 val = DAC_READ(sc, FFB_DAC_VALUE);
528 528
529 switch (cmd) { 529 switch (cmd) {
530 case WSDISPLAYIO_GVIDEO: 530 case WSDISPLAYIO_GVIDEO:
531 *data = val & 1; 531 *data = val & 1;
532 return(0); 532 return(0);
533 break; 533 break;
534 case WSDISPLAYIO_SVIDEO: 534 case WSDISPLAYIO_SVIDEO:
535 if (*data == WSDISPLAYIO_VIDEO_OFF) 535 if (*data == WSDISPLAYIO_VIDEO_OFF)
536 val &= ~1; 536 val &= ~1;
537 else if (*data == WSDISPLAYIO_VIDEO_ON) 537 else if (*data == WSDISPLAYIO_VIDEO_ON)
538 val |= 1; 538 val |= 1;
539 else 539 else
540 return(EINVAL); 540 return(EINVAL);
541 break; 541 break;
542 default: 542 default:
543 return(EINVAL); 543 return(EINVAL);
544 } 544 }
545 545
546 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_TGC); 546 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_TGC);
547 DAC_WRITE(sc, FFB_DAC_VALUE, val); 547 DAC_WRITE(sc, FFB_DAC_VALUE, val);
548  548
549 if ((val & 1) && sc->sc_needredraw) { 549 if ((val & 1) && sc->sc_needredraw) {
550 if (ms != NULL) { 550 if (ms != NULL) {
551 if ((sc->sc_mode == WSDISPLAYIO_MODE_EMUL) &&  551 if ((sc->sc_mode == WSDISPLAYIO_MODE_EMUL) &&
552 (sc->sc_locked == 0)) { 552 (sc->sc_locked == 0)) {
553 ffb_ras_init(sc); 553 ffb_ras_init(sc);
554 vcons_redraw_screen(ms); 554 vcons_redraw_screen(ms);
555 } 555 }
556 } 556 }
557 } 557 }
558 558
559 return(0); 559 return(0);
560} 560}
561 561
562paddr_t 562paddr_t
563ffb_mmap(void *vsc, void *vs, off_t off, int prot) 563ffb_mmap(void *vsc, void *vs, off_t off, int prot)
564{ 564{
565 struct vcons_data *vd = vsc; 565 struct vcons_data *vd = vsc;
566 struct ffb_softc *sc = vd->cookie; 566 struct ffb_softc *sc = vd->cookie;
567 int i; 567 int i;
568 568
569 switch (sc->sc_mode) { 569 switch (sc->sc_mode) {
570 case WSDISPLAYIO_MODE_MAPPED: 570 case WSDISPLAYIO_MODE_MAPPED:
571 for (i = 0; i < sc->sc_nreg; i++) { 571 for (i = 0; i < sc->sc_nreg; i++) {
572 /* Before this set? */ 572 /* Before this set? */
573 if (off < sc->sc_addrs[i]) 573 if (off < sc->sc_addrs[i])
574 continue; 574 continue;
575 /* After this set? */ 575 /* After this set? */
576 if (off >= (sc->sc_addrs[i] + sc->sc_sizes[i])) 576 if (off >= (sc->sc_addrs[i] + sc->sc_sizes[i]))
577 continue; 577 continue;
578 578
579 return (bus_space_mmap(sc->sc_bt, sc->sc_addrs[i], 579 return (bus_space_mmap(sc->sc_bt, sc->sc_addrs[i],
580 off - sc->sc_addrs[i], prot, BUS_SPACE_MAP_LINEAR)); 580 off - sc->sc_addrs[i], prot, BUS_SPACE_MAP_LINEAR));
581 } 581 }
582 break; 582 break;
583#ifdef WSDISPLAYIO_MODE_DUMBFB 583#ifdef WSDISPLAYIO_MODE_DUMBFB
584 case WSDISPLAYIO_MODE_DUMBFB: 584 case WSDISPLAYIO_MODE_DUMBFB:
585 if (sc->sc_nreg < FFB_REG_DFB24) 585 if (sc->sc_nreg < FFB_REG_DFB24)
586 break; 586 break;
587 if (off >= 0 && off < sc->sc_sizes[FFB_REG_DFB24]) 587 if (off >= 0 && off < sc->sc_sizes[FFB_REG_DFB24])
588 return (bus_space_mmap(sc->sc_bt, 588 return (bus_space_mmap(sc->sc_bt,
589 sc->sc_addrs[FFB_REG_DFB24], off, prot, 589 sc->sc_addrs[FFB_REG_DFB24], off, prot,
590 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE)); 590 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE));
591 break; 591 break;
592#endif 592#endif
593 } 593 }
594 return (-1); 594 return (-1);
595} 595}
596 596
597void 597void
598ffb_ras_fifo_wait(struct ffb_softc *sc, int n) 598ffb_ras_fifo_wait(struct ffb_softc *sc, int n)
599{ 599{
600 int32_t cache = sc->sc_fifo_cache; 600 int32_t cache = sc->sc_fifo_cache;
601 601
602 if (cache < n) { 602 if (cache < n) {
603 do { 603 do {
604 cache = FBC_READ(sc, FFB_FBC_UCSR); 604 cache = FBC_READ(sc, FFB_FBC_UCSR);
605 cache = (cache & FBC_UCSR_FIFO_MASK) - 8; 605 cache = (cache & FBC_UCSR_FIFO_MASK) - 8;
606 } while (cache < n); 606 } while (cache < n);
607 } 607 }
608 sc->sc_fifo_cache = cache - n; 608 sc->sc_fifo_cache = cache - n;
609} 609}
610 610
611void 611void
612ffb_ras_wait(struct ffb_softc *sc) 612ffb_ras_wait(struct ffb_softc *sc)
613{ 613{
614 uint32_t ucsr, r; 614 uint32_t ucsr, r;
615 615
616 while (1) { 616 while (1) {
617 ucsr = FBC_READ(sc, FFB_FBC_UCSR); 617 ucsr = FBC_READ(sc, FFB_FBC_UCSR);
618 if ((ucsr & (FBC_UCSR_FB_BUSY|FBC_UCSR_RP_BUSY)) == 0) 618 if ((ucsr & (FBC_UCSR_FB_BUSY|FBC_UCSR_RP_BUSY)) == 0)
619 break; 619 break;
620 r = ucsr & (FBC_UCSR_READ_ERR | FBC_UCSR_FIFO_OVFL); 620 r = ucsr & (FBC_UCSR_READ_ERR | FBC_UCSR_FIFO_OVFL);
621 if (r != 0) 621 if (r != 0)
622 FBC_WRITE(sc, FFB_FBC_UCSR, r); 622 FBC_WRITE(sc, FFB_FBC_UCSR, r);
623 } 623 }
624} 624}
625 625
626void 626void
627ffb_ras_init(struct ffb_softc *sc) 627ffb_ras_init(struct ffb_softc *sc)
628{ 628{
629 uint32_t fbc; 629 uint32_t fbc;
630 630
631 if (sc->sc_width > 1280) { 631 if (sc->sc_width > 1280) {
632 DPRINTF(("ffb_ras_init: high resolution.\n")); 632 DPRINTF(("ffb_ras_init: high resolution.\n"));
633 fbc = FFB_FBC_WM_COMBINED | FFB_FBC_WE_FORCEON | 633 fbc = FFB_FBC_WM_COMBINED | FFB_FBC_WE_FORCEON |
634 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_XE_ON; 634 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_XE_ON;
635 } else { 635 } else {
636 DPRINTF(("ffb_ras_init: standard resolution.\n")); 636 DPRINTF(("ffb_ras_init: standard resolution.\n"));
637 fbc = FFB_FBC_XE_OFF; 637 fbc = FFB_FBC_XE_OFF;
638 } 638 }
639 ffb_ras_fifo_wait(sc, 7); 639 ffb_ras_fifo_wait(sc, 7);
640 DPRINTF(("WID: %08x\n", FBC_READ(sc, FFB_FBC_WID))); 640 DPRINTF(("WID: %08x\n", FBC_READ(sc, FFB_FBC_WID)));
641 FBC_WRITE(sc, FFB_FBC_WID, 0x0); 641 FBC_WRITE(sc, FFB_FBC_WID, 0x0);
642 FBC_WRITE(sc, FFB_FBC_PPC, 642 FBC_WRITE(sc, FFB_FBC_PPC,
643 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |  643 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |
644 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |  644 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |
645 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); 645 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID);
646  646
647 fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A | FFB_FBC_SB_BOTH | 647 fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A | FFB_FBC_SB_BOTH |
648 FFB_FBC_RGBE_MASK; 648 FFB_FBC_RGBE_MASK;
649 DPRINTF(("%s: fbc is %08x\n", __func__, fbc)); 649 DPRINTF(("%s: fbc is %08x\n", __func__, fbc));
650 FBC_WRITE(sc, FFB_FBC_FBC, fbc); 650 FBC_WRITE(sc, FFB_FBC_FBC, fbc);
651 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); 651 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW);
652 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE); 652 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
653 FBC_WRITE(sc, FFB_FBC_PMASK, 0xffffffff); 653 FBC_WRITE(sc, FFB_FBC_PMASK, 0xffffffff);
654 FBC_WRITE(sc, FFB_FBC_FONTINC, 0x10000); 654 FBC_WRITE(sc, FFB_FBC_FONTINC, 0x10000);
655 ffb_ras_fifo_wait(sc, 5); 655 ffb_ras_fifo_wait(sc, 5);
656 sc->sc_fg_cache = 0; 656 sc->sc_fg_cache = 0;
657 FBC_WRITE(sc, FFB_FBC_FG, sc->sc_fg_cache); 657 FBC_WRITE(sc, FFB_FBC_FG, sc->sc_fg_cache);
658 sc->sc_bg_cache = 0; 658 sc->sc_bg_cache = 0;
659 FBC_WRITE(sc, FFB_FBC_BG, sc->sc_bg_cache); 659 FBC_WRITE(sc, FFB_FBC_BG, sc->sc_bg_cache);
660 FBC_WRITE(sc, FFB_FBC_BLENDC, FFB_BLENDC_FORCE_ONE | 660 FBC_WRITE(sc, FFB_FBC_BLENDC, FFB_BLENDC_FORCE_ONE |
661 FFB_BLENDC_DF_ONE_M_A | 661 FFB_BLENDC_DF_ONE_M_A |
662 FFB_BLENDC_SF_A); 662 FFB_BLENDC_SF_A);
663 FBC_WRITE(sc, FFB_FBC_BLENDC1, 0); 663 FBC_WRITE(sc, FFB_FBC_BLENDC1, 0);
664 FBC_WRITE(sc, FFB_FBC_BLENDC2, 0); 664 FBC_WRITE(sc, FFB_FBC_BLENDC2, 0);
665 ffb_ras_wait(sc); 665 ffb_ras_wait(sc);
666} 666}
667 667
668void 668void
669ffb_ras_eraserows(void *cookie, int row, int n, long attr) 669ffb_ras_eraserows(void *cookie, int row, int n, long attr)
670{ 670{
671 struct rasops_info *ri = cookie; 671 struct rasops_info *ri = cookie;
672 struct vcons_screen *scr = ri->ri_hw; 672 struct vcons_screen *scr = ri->ri_hw;
673 struct ffb_softc *sc = scr->scr_cookie; 673 struct ffb_softc *sc = scr->scr_cookie;
674 674
675 if (row < 0) { 675 if (row < 0) {
676 n += row; 676 n += row;
677 row = 0; 677 row = 0;
678 } 678 }
679 if (row + n > ri->ri_rows) 679 if (row + n > ri->ri_rows)
680 n = ri->ri_rows - row; 680 n = ri->ri_rows - row;
681 if (n <= 0) 681 if (n <= 0)
682 return; 682 return;
683  683
684 ffb_ras_fill(sc); 684 ffb_ras_fill(sc);
685 ffb_ras_setfg(sc, ri->ri_devcmap[(attr >> 16) & 0xf]); 685 ffb_ras_setfg(sc, ri->ri_devcmap[(attr >> 16) & 0xf]);
686 ffb_ras_fifo_wait(sc, 4); 686 ffb_ras_fifo_wait(sc, 4);
687 if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) { 687 if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
688 FBC_WRITE(sc, FFB_FBC_BY, 0); 688 FBC_WRITE(sc, FFB_FBC_BY, 0);
689 FBC_WRITE(sc, FFB_FBC_BX, 0); 689 FBC_WRITE(sc, FFB_FBC_BX, 0);
690 FBC_WRITE(sc, FFB_FBC_BH, ri->ri_height); 690 FBC_WRITE(sc, FFB_FBC_BH, ri->ri_height);
691 FBC_WRITE(sc, FFB_FBC_BW, ri->ri_width); 691 FBC_WRITE(sc, FFB_FBC_BW, ri->ri_width);
692 ri->ri_flg &= ~RI_CURSOR; 692 ri->ri_flg &= ~RI_CURSOR;
693 } else { 693 } else {
694 row *= ri->ri_font->fontheight; 694 row *= ri->ri_font->fontheight;
695 FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + row); 695 FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + row);
696 FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin); 696 FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin);
697 FBC_WRITE(sc, FFB_FBC_BH, n * ri->ri_font->fontheight); 697 FBC_WRITE(sc, FFB_FBC_BH, n * ri->ri_font->fontheight);
698 FBC_WRITE(sc, FFB_FBC_BW, ri->ri_emuwidth); 698 FBC_WRITE(sc, FFB_FBC_BW, ri->ri_emuwidth);
699 } 699 }
700 SYNC; 700 SYNC;
701} 701}
702 702
703void 703void
704ffb_ras_erasecols(void *cookie, int row, int col, int n, long attr) 704ffb_ras_erasecols(void *cookie, int row, int col, int n, long attr)
705{ 705{
706 struct rasops_info *ri = cookie; 706 struct rasops_info *ri = cookie;
707 struct vcons_screen *scr = ri->ri_hw; 707 struct vcons_screen *scr = ri->ri_hw;
708 struct ffb_softc *sc = scr->scr_cookie; 708 struct ffb_softc *sc = scr->scr_cookie;
709 709
710 if ((row < 0) || (row >= ri->ri_rows)) 710 if ((row < 0) || (row >= ri->ri_rows))
711 return; 711 return;
712 if (col < 0) { 712 if (col < 0) {
713 n += col; 713 n += col;
714 col = 0; 714 col = 0;
715 } 715 }
716 if (col + n > ri->ri_cols) 716 if (col + n > ri->ri_cols)
717 n = ri->ri_cols - col; 717 n = ri->ri_cols - col;
718 if (n <= 0) 718 if (n <= 0)
719 return; 719 return;
720 720
721 n *= ri->ri_font->fontwidth; 721 n *= ri->ri_font->fontwidth;
722 col *= ri->ri_font->fontwidth; 722 col *= ri->ri_font->fontwidth;
723 row *= ri->ri_font->fontheight; 723 row *= ri->ri_font->fontheight;
724 724
725 ffb_ras_fill(sc); 725 ffb_ras_fill(sc);
726 ffb_ras_setfg(sc, ri->ri_devcmap[(attr >> 16) & 0xf]); 726 ffb_ras_setfg(sc, ri->ri_devcmap[(attr >> 16) & 0xf]);
727 ffb_ras_fifo_wait(sc, 4); 727 ffb_ras_fifo_wait(sc, 4);
728 FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + row); 728 FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + row);
729 FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin + col); 729 FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin + col);
730 FBC_WRITE(sc, FFB_FBC_BH, ri->ri_font->fontheight); 730 FBC_WRITE(sc, FFB_FBC_BH, ri->ri_font->fontheight);
731 FBC_WRITE(sc, FFB_FBC_BW, n); 731 FBC_WRITE(sc, FFB_FBC_BW, n);
732 SYNC; 732 SYNC;
733} 733}
734 734
735void 735void
736ffb_ras_fill(struct ffb_softc *sc) 736ffb_ras_fill(struct ffb_softc *sc)
737{ 737{
738 ffb_ras_fifo_wait(sc, 3); 738 ffb_ras_fifo_wait(sc, 3);
739 FBC_WRITE(sc, FFB_FBC_PPC, 739 FBC_WRITE(sc, FFB_FBC_PPC,
740 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |  740 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |
741 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |  741 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |
742 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); 742 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID);
743 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); 743 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW);
744 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE); 744 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
745 SYNC; 745 SYNC;
746} 746}
747 747
748void 748void
749ffb_ras_invert(struct ffb_softc *sc) 749ffb_ras_invert(struct ffb_softc *sc)
750{ 750{
751 ffb_ras_fifo_wait(sc, 3); 751 ffb_ras_fifo_wait(sc, 3);
752 FBC_WRITE(sc, FFB_FBC_PPC, 752 FBC_WRITE(sc, FFB_FBC_PPC,
753 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |  753 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |
754 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |  754 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |
755 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); 755 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID);
756 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_INVERT); 756 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_INVERT);
757 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE); 757 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
758 SYNC; 758 SYNC;
759} 759}
760 760
761void 761void
762ffb_ras_copyrows(void *cookie, int src, int dst, int n) 762ffb_ras_copyrows(void *cookie, int src, int dst, int n)
763{ 763{
764 struct rasops_info *ri = cookie; 764 struct rasops_info *ri = cookie;
765 struct vcons_screen *scr = ri->ri_hw; 765 struct vcons_screen *scr = ri->ri_hw;
766 struct ffb_softc *sc = scr->scr_cookie; 766 struct ffb_softc *sc = scr->scr_cookie;
767 767
768 if (dst == src) 768 if (dst == src)
769 return; 769 return;
770 if (src < 0) { 770 if (src < 0) {
771 n += src; 771 n += src;
772 src = 0; 772 src = 0;
773 } 773 }
774 if ((src + n) > ri->ri_rows) 774 if ((src + n) > ri->ri_rows)
775 n = ri->ri_rows - src; 775 n = ri->ri_rows - src;
776 if (dst < 0) { 776 if (dst < 0) {
777 n += dst; 777 n += dst;
778 dst = 0; 778 dst = 0;
779 } 779 }
780 if ((dst + n) > ri->ri_rows) 780 if ((dst + n) > ri->ri_rows)
781 n = ri->ri_rows - dst; 781 n = ri->ri_rows - dst;
782 if (n <= 0) 782 if (n <= 0)
783 return; 783 return;
784 n *= ri->ri_font->fontheight; 784 n *= ri->ri_font->fontheight;
785 src *= ri->ri_font->fontheight; 785 src *= ri->ri_font->fontheight;
786 dst *= ri->ri_font->fontheight; 786 dst *= ri->ri_font->fontheight;
787 787
788 ffb_ras_fifo_wait(sc, 9); 788 ffb_ras_fifo_wait(sc, 9);
789 FBC_WRITE(sc, FFB_FBC_PPC, 789 FBC_WRITE(sc, FFB_FBC_PPC,
790 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |  790 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |
791 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |  791 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |
792 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); 792 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID);
793 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_OLD | (FBC_ROP_OLD << 8)); 793 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_OLD | (FBC_ROP_OLD << 8));
794 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_VSCROLL); 794 FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_VSCROLL);
795 FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + src); 795 FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + src);
796 FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin); 796 FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin);
797 FBC_WRITE(sc, FFB_FBC_DY, ri->ri_yorigin + dst); 797 FBC_WRITE(sc, FFB_FBC_DY, ri->ri_yorigin + dst);
798 FBC_WRITE(sc, FFB_FBC_DX, ri->ri_xorigin); 798 FBC_WRITE(sc, FFB_FBC_DX, ri->ri_xorigin);
799 FBC_WRITE(sc, FFB_FBC_BH, n); 799 FBC_WRITE(sc, FFB_FBC_BH, n);
800 FBC_WRITE(sc, FFB_FBC_BW, ri->ri_emuwidth); 800 FBC_WRITE(sc, FFB_FBC_BW, ri->ri_emuwidth);
801 SYNC; 801 SYNC;
802} 802}
803 803
804static void 804static void
805ffb_ras_setfg(struct ffb_softc *sc, int32_t fg) 805ffb_ras_setfg(struct ffb_softc *sc, int32_t fg)
806{ 806{
807 ffb_ras_fifo_wait(sc, 1); 807 ffb_ras_fifo_wait(sc, 1);
808 if (fg == sc->sc_fg_cache) 808 if (fg == sc->sc_fg_cache)
809 return; 809 return;
810 sc->sc_fg_cache = fg; 810 sc->sc_fg_cache = fg;
811 FBC_WRITE(sc, FFB_FBC_FG, fg); 811 FBC_WRITE(sc, FFB_FBC_FG, fg);
812 SYNC; 812 SYNC;
813} 813}
814 814
815static void 815static void
816ffb_ras_setbg(struct ffb_softc *sc, int32_t bg) 816ffb_ras_setbg(struct ffb_softc *sc, int32_t bg)
817{ 817{
818 ffb_ras_fifo_wait(sc, 1); 818 ffb_ras_fifo_wait(sc, 1);
819 if (bg == sc->sc_bg_cache) 819 if (bg == sc->sc_bg_cache)
820 return; 820 return;
821 sc->sc_bg_cache = bg; 821 sc->sc_bg_cache = bg;
822 FBC_WRITE(sc, FFB_FBC_BG, bg); 822 FBC_WRITE(sc, FFB_FBC_BG, bg);
823 SYNC; 823 SYNC;
824} 824}
825 825
826/* frame buffer generic driver support functions */  826/* frame buffer generic driver support functions */
827static void 827static void
828ffbfb_unblank(device_t dev) 828ffbfb_unblank(device_t dev)
829{ 829{
830 struct ffb_softc *sc = device_private(dev); 830 struct ffb_softc *sc = device_private(dev);
831 struct vcons_screen *ms = sc->vd.active; 831 struct vcons_screen *ms = sc->vd.active;
832 u_int on = 1; 832 u_int on = 1;
833 int redraw = 0; 833 int redraw = 0;
834  834
835 ffb_ras_init(sc); 835 ffb_ras_init(sc);
836 if (sc->sc_locked) { 836 if (sc->sc_locked) {
837 sc->sc_locked = 0; 837 sc->sc_locked = 0;
838 redraw = 1; 838 redraw = 1;
839 } 839 }
840  840
841 ffb_blank(sc, WSDISPLAYIO_SVIDEO, &on); 841 ffb_blank(sc, WSDISPLAYIO_SVIDEO, &on);
842#if 0 842#if 0
843 if ((sc->vd.active != &ffb_console_screen) && 843 if ((sc->vd.active != &ffb_console_screen) &&
844 (ffb_console_screen.scr_flags & VCONS_SCREEN_IS_STATIC)) { 844 (ffb_console_screen.scr_flags & VCONS_SCREEN_IS_STATIC)) {
845 /*  845 /*
846 * force-switch to the console screen. 846 * force-switch to the console screen.
847 * Caveat: the higher layer will think we're still on the 847 * Caveat: the higher layer will think we're still on the
848 * other screen 848 * other screen
849 */ 849 */
850  850
851 SCREEN_INVISIBLE(sc->vd.active); 851 SCREEN_INVISIBLE(sc->vd.active);
852 sc->vd.active = &ffb_console_screen; 852 sc->vd.active = &ffb_console_screen;
853 SCREEN_VISIBLE(sc->vd.active); 853 SCREEN_VISIBLE(sc->vd.active);
854 ms = sc->vd.active; 854 ms = sc->vd.active;
855 redraw = 1; 855 redraw = 1;
856 } 856 }
857#endif  857#endif
858 if (redraw) { 858 if (redraw) {
859 vcons_redraw_screen(ms); 859 vcons_redraw_screen(ms);
860 } 860 }
861} 861}
862 862
863int 863int
864ffbfb_open(dev_t dev, int flags, int mode, struct lwp *l) 864ffbfb_open(dev_t dev, int flags, int mode, struct lwp *l)
865{ 865{
866 struct ffb_softc *sc; 866 struct ffb_softc *sc;
867 867
868 sc = device_lookup_private(&ffb_cd, minor(dev)); 868 sc = device_lookup_private(&ffb_cd, minor(dev));
869 if (sc == NULL) 869 if (sc == NULL)
870 return ENXIO; 870 return ENXIO;
871  871
872 sc->sc_locked = 1; 872 sc->sc_locked = 1;
873 return 0; 873 return 0;
874} 874}
875 875
876int 876int
877ffbfb_close(dev_t dev, int flags, int mode, struct lwp *l) 877ffbfb_close(dev_t dev, int flags, int mode, struct lwp *l)
878{ 878{
879 struct ffb_softc *sc = device_lookup_private(&ffb_cd, minor(dev)); 879 struct ffb_softc *sc = device_lookup_private(&ffb_cd, minor(dev));
880 struct vcons_screen *ms = sc->vd.active; 880 struct vcons_screen *ms = sc->vd.active;
881  881
882 sc->sc_locked = 0; 882 sc->sc_locked = 0;
883 if (ms != NULL) { 883 if (ms != NULL) {
884 if ((sc->sc_mode == WSDISPLAYIO_MODE_EMUL) && 884 if ((sc->sc_mode == WSDISPLAYIO_MODE_EMUL) &&
885 (sc->sc_locked == 0)) { 885 (sc->sc_locked == 0)) {
886 ffb_ras_init(sc); 886 ffb_ras_init(sc);
887 vcons_redraw_screen(ms); 887 vcons_redraw_screen(ms);
888 } 888 }
889 } 889 }
890 return 0; 890 return 0;
891} 891}
892 892
893int 893int
894ffbfb_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 894ffbfb_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
895{ 895{
896 struct ffb_softc *sc = device_lookup_private(&ffb_cd, minor(dev)); 896 struct ffb_softc *sc = device_lookup_private(&ffb_cd, minor(dev));
897 897
898 return ffb_ioctl(&sc->vd, NULL, cmd, data, flags, l); 898 return ffb_ioctl(&sc->vd, NULL, cmd, data, flags, l);
899} 899}
900 900
901paddr_t 901paddr_t
902ffbfb_mmap(dev_t dev, off_t off, int prot) 902ffbfb_mmap(dev_t dev, off_t off, int prot)
903{ 903{
904 struct ffb_softc *sc = device_lookup_private(&ffb_cd, minor(dev)); 904 struct ffb_softc *sc = device_lookup_private(&ffb_cd, minor(dev));
905 uint64_t size; 905 uint64_t size;
906 int i, reg; 906 int i, reg;
907 off_t o; 907 off_t o;
908 908
909 /* 909 /*
910 * off is a magic cookie (see xfree86/drivers/sunffb/ffb.h), 910 * off is a magic cookie (see xfree86/drivers/sunffb/ffb.h),
911 * which we map to an index into the "reg" property, and use 911 * which we map to an index into the "reg" property, and use
912 * our copy of the firmware data as arguments for the real 912 * our copy of the firmware data as arguments for the real
913 * mapping. 913 * mapping.
914 */ 914 */
915 static struct { unsigned long voff; int reg; long flags; } map[] = { 915 static struct { unsigned long voff; int reg; long flags; } map[] = {
916 { 0x00000000, FFB_REG_SFB8R, BUS_SPACE_MAP_PREFETCHABLE }, 916 { 0x00000000, FFB_REG_SFB8R, BUS_SPACE_MAP_PREFETCHABLE },
917 { 0x00400000, FFB_REG_SFB8G, BUS_SPACE_MAP_PREFETCHABLE }, 917 { 0x00400000, FFB_REG_SFB8G, BUS_SPACE_MAP_PREFETCHABLE },
918 { 0x00800000, FFB_REG_SFB8B, BUS_SPACE_MAP_PREFETCHABLE }, 918 { 0x00800000, FFB_REG_SFB8B, BUS_SPACE_MAP_PREFETCHABLE },
919 { 0x00c00000, FFB_REG_SFB8X, BUS_SPACE_MAP_PREFETCHABLE }, 919 { 0x00c00000, FFB_REG_SFB8X, BUS_SPACE_MAP_PREFETCHABLE },
920 { 0x01000000, FFB_REG_SFB32, BUS_SPACE_MAP_PREFETCHABLE }, 920 { 0x01000000, FFB_REG_SFB32, BUS_SPACE_MAP_PREFETCHABLE },
921 { 0x02000000, FFB_REG_SFB64, BUS_SPACE_MAP_PREFETCHABLE }, 921 { 0x02000000, FFB_REG_SFB64, BUS_SPACE_MAP_PREFETCHABLE },
922 { 0x04000000, FFB_REG_FBC, 0 }, 922 { 0x04000000, FFB_REG_FBC, 0 },
923 { 0x04004000, FFB_REG_DFB8R, BUS_SPACE_MAP_PREFETCHABLE }, 923 { 0x04004000, FFB_REG_DFB8R, BUS_SPACE_MAP_PREFETCHABLE },
924 { 0x04404000, FFB_REG_DFB8G, BUS_SPACE_MAP_PREFETCHABLE }, 924 { 0x04404000, FFB_REG_DFB8G, BUS_SPACE_MAP_PREFETCHABLE },
925 { 0x04804000, FFB_REG_DFB8B, BUS_SPACE_MAP_PREFETCHABLE }, 925 { 0x04804000, FFB_REG_DFB8B, BUS_SPACE_MAP_PREFETCHABLE },
926 { 0x04c04000, FFB_REG_DFB8X, BUS_SPACE_MAP_PREFETCHABLE }, 926 { 0x04c04000, FFB_REG_DFB8X, BUS_SPACE_MAP_PREFETCHABLE },
927 { 0x05004000, FFB_REG_DFB24, BUS_SPACE_MAP_PREFETCHABLE }, 927 { 0x05004000, FFB_REG_DFB24, BUS_SPACE_MAP_PREFETCHABLE },
928 { 0x06004000, FFB_REG_DFB32, BUS_SPACE_MAP_PREFETCHABLE }, 928 { 0x06004000, FFB_REG_DFB32, BUS_SPACE_MAP_PREFETCHABLE },
929 { 0x07004000, FFB_REG_DFB422A, BUS_SPACE_MAP_PREFETCHABLE }, 929 { 0x07004000, FFB_REG_DFB422A, BUS_SPACE_MAP_PREFETCHABLE },
930 { 0x0bc06000, FFB_REG_DAC, 0 }, 930 { 0x0bc06000, FFB_REG_DAC, 0 },
931 { 0x0bc08000, FFB_REG_PROM, 0 }, 931 { 0x0bc08000, FFB_REG_PROM, 0 },
932 { 0x0bc18000, 0, 0 } 932 { 0x0bc18000, 0, 0 }
933 }; 933 };
934 934
935 /* special value "FFB_EXP_VOFF" - not backed by any "reg" entry */ 935 /* special value "FFB_EXP_VOFF" - not backed by any "reg" entry */
936 if (off == 0x0bc18000) 936 if (off == 0x0bc18000)
937 return bus_space_mmap(sc->sc_bt, sc->sc_addrs[FFB_REG_PROM], 937 return bus_space_mmap(sc->sc_bt, sc->sc_addrs[FFB_REG_PROM],
938 0x00200000, prot, BUS_SPACE_MAP_LINEAR); 938 0x00200000, prot, BUS_SPACE_MAP_LINEAR);
939  939
940 /*  940 /*
941 * FFB_VOFF_FBC_KREGS - used by afbinit to upload firmware. We should  941 * FFB_VOFF_FBC_KREGS - used by afbinit to upload firmware. We should
942 * probably mmap them only on afb boards  942 * probably mmap them only on afb boards
943 */ 943 */
944 if ((off >= 0x0bc04000) && (off < 0x0bc06000)) 944 if ((off >= 0x0bc04000) && (off < 0x0bc06000))
945 return bus_space_mmap(sc->sc_bt, sc->sc_addrs[FFB_REG_PROM],  945 return bus_space_mmap(sc->sc_bt, sc->sc_addrs[FFB_REG_PROM],
946 0x00610000 + (off - 0x0bc04000), prot,  946 0x00610000 + (off - 0x0bc04000), prot,
947 BUS_SPACE_MAP_LINEAR); 947 BUS_SPACE_MAP_LINEAR);
948  948
949#define NELEMS(arr) (sizeof(arr)/sizeof((arr)[0])) 949#define NELEMS(arr) (sizeof(arr)/sizeof((arr)[0]))
950 950
951 /* the map is ordered by voff */ 951 /* the map is ordered by voff */
952 for (i = 0; i < NELEMS(map)-1; i++) { 952 for (i = 0; i < NELEMS(map)-1; i++) {
953 reg = map[i].reg; 953 reg = map[i].reg;
954 /* the number of entries in reg seems to vary */ 954 /* the number of entries in reg seems to vary */
955 if (reg < sc->sc_nreg) { 955 if (reg < sc->sc_nreg) {
956 size = uimin((map[i + 1].voff - map[i].voff),  956 size = uimin((map[i + 1].voff - map[i].voff),
957 sc->sc_sizes[reg]); 957 sc->sc_sizes[reg]);
958 if ((off >= map[i].voff) &&  958 if ((off >= map[i].voff) &&
959 (off < (map[i].voff + size))) { 959 (off < (map[i].voff + size))) {
960 o = off - map[i].voff; 960 o = off - map[i].voff;
961 return bus_space_mmap(sc->sc_bt,  961 return bus_space_mmap(sc->sc_bt,
962 sc->sc_addrs[reg], o, prot,  962 sc->sc_addrs[reg], o, prot,
963 BUS_SPACE_MAP_LINEAR | map[i].flags); 963 BUS_SPACE_MAP_LINEAR | map[i].flags);
964 } 964 }
965 } 965 }
966 } 966 }
967 967
968 return -1; 968 return -1;
969} 969}
970 970
971void 971void
972ffb_clearscreen(struct ffb_softc *sc) 972ffb_clearscreen(struct ffb_softc *sc)
973{ 973{
974 struct rasops_info *ri = &ffb_console_screen.scr_ri; 974 struct rasops_info *ri = &ffb_console_screen.scr_ri;
975 ffb_ras_fill(sc); 975 ffb_ras_fill(sc);
976 ffb_ras_setfg(sc, ri->ri_devcmap[WS_DEFAULT_BG]); 976 ffb_ras_setfg(sc, ri->ri_devcmap[WS_DEFAULT_BG]);
977 ffb_ras_fifo_wait(sc, 4); 977 ffb_ras_fifo_wait(sc, 4);
978 FBC_WRITE(sc, FFB_FBC_BY, 0); 978 FBC_WRITE(sc, FFB_FBC_BY, 0);
979 FBC_WRITE(sc, FFB_FBC_BX, 0); 979 FBC_WRITE(sc, FFB_FBC_BX, 0);
980 FBC_WRITE(sc, FFB_FBC_BH, sc->sc_height); 980 FBC_WRITE(sc, FFB_FBC_BH, sc->sc_height);
981 FBC_WRITE(sc, FFB_FBC_BW, sc->sc_width); 981 FBC_WRITE(sc, FFB_FBC_BW, sc->sc_width);
982} 982}
983 983
984void 984void
985ffb_cursor(void *cookie, int on, int row, int col) 985ffb_cursor(void *cookie, int on, int row, int col)
986{ 986{
987 struct rasops_info *ri = cookie; 987 struct rasops_info *ri = cookie;
988 struct vcons_screen *scr; 988 struct vcons_screen *scr;
989 struct ffb_softc *sc; 989 struct ffb_softc *sc;
990 int x, y, wi, he; 990 int x, y, wi, he;
991  991
992 if (cookie != NULL) { 992 if (cookie != NULL) {
993 scr = ri->ri_hw; 993 scr = ri->ri_hw;
994 sc = scr->scr_cookie; 994 sc = scr->scr_cookie;
995  995
996 wi = ri->ri_font->fontwidth; 996 wi = ri->ri_font->fontwidth;
997 he = ri->ri_font->fontheight; 997 he = ri->ri_font->fontheight;
998 998
999 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 999 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1000  1000
1001 if (ri->ri_flg & RI_CURSOR) { 1001 if (ri->ri_flg & RI_CURSOR) {
1002 1002
1003 /* remove cursor */ 1003 /* remove cursor */
1004 x = ri->ri_ccol * wi + ri->ri_xorigin; 1004 x = ri->ri_ccol * wi + ri->ri_xorigin;
1005 y = ri->ri_crow * he + ri->ri_yorigin; 1005 y = ri->ri_crow * he + ri->ri_yorigin;
1006 1006
1007 ffb_ras_invert(sc); 1007 ffb_ras_invert(sc);
1008 ffb_ras_fifo_wait(sc, 4); 1008 ffb_ras_fifo_wait(sc, 4);
1009 FBC_WRITE(sc, FFB_FBC_BY, y); 1009 FBC_WRITE(sc, FFB_FBC_BY, y);
1010 FBC_WRITE(sc, FFB_FBC_BX, x); 1010 FBC_WRITE(sc, FFB_FBC_BX, x);
1011 FBC_WRITE(sc, FFB_FBC_BH, he); 1011 FBC_WRITE(sc, FFB_FBC_BH, he);
1012 FBC_WRITE(sc, FFB_FBC_BW, wi); 1012 FBC_WRITE(sc, FFB_FBC_BW, wi);
1013 1013
1014 ri->ri_flg &= ~RI_CURSOR; 1014 ri->ri_flg &= ~RI_CURSOR;
1015 } 1015 }
1016 ri->ri_crow = row; 1016 ri->ri_crow = row;
1017 ri->ri_ccol = col; 1017 ri->ri_ccol = col;
1018 if (on) 1018 if (on)
1019 { 1019 {
1020 x = ri->ri_ccol * wi + ri->ri_xorigin; 1020 x = ri->ri_ccol * wi + ri->ri_xorigin;
1021 y = ri->ri_crow * he + ri->ri_yorigin; 1021 y = ri->ri_crow * he + ri->ri_yorigin;
1022 1022
1023 ffb_ras_invert(sc); 1023 ffb_ras_invert(sc);
1024 ffb_ras_fifo_wait(sc, 4); 1024 ffb_ras_fifo_wait(sc, 4);
1025 FBC_WRITE(sc, FFB_FBC_BY, y); 1025 FBC_WRITE(sc, FFB_FBC_BY, y);
1026 FBC_WRITE(sc, FFB_FBC_BX, x); 1026 FBC_WRITE(sc, FFB_FBC_BX, x);
1027 FBC_WRITE(sc, FFB_FBC_BH, he); 1027 FBC_WRITE(sc, FFB_FBC_BH, he);
1028 FBC_WRITE(sc, FFB_FBC_BW, wi); 1028 FBC_WRITE(sc, FFB_FBC_BW, wi);
1029 1029
1030 ri->ri_flg |= RI_CURSOR; 1030 ri->ri_flg |= RI_CURSOR;
1031 } 1031 }
1032 } else { 1032 } else {
1033 ri->ri_crow = row; 1033 ri->ri_crow = row;
1034 ri->ri_ccol = col; 1034 ri->ri_ccol = col;
1035 ri->ri_flg &= ~RI_CURSOR; 1035 ri->ri_flg &= ~RI_CURSOR;
1036 } 1036 }
1037 } 1037 }
1038} 1038}
1039 1039
1040/* mono bitmap font */ 1040/* mono bitmap font */
1041void 1041void
1042ffb_putchar_mono(void *cookie, int row, int col, u_int c, long attr) 1042ffb_putchar_mono(void *cookie, int row, int col, u_int c, long attr)
1043{ 1043{
1044 struct rasops_info *ri = cookie; 1044 struct rasops_info *ri = cookie;
1045 struct vcons_screen *scr = ri->ri_hw; 1045 struct vcons_screen *scr = ri->ri_hw;
1046 struct wsdisplay_font *font = PICK_FONT(ri, c); 1046 struct wsdisplay_font *font = PICK_FONT(ri, c);
1047 struct ffb_softc *sc = scr->scr_cookie; 1047 struct ffb_softc *sc = scr->scr_cookie;
1048 void *data; 1048 void *data;
1049 uint32_t fg, bg; 1049 uint32_t fg, bg;
1050 int i; 1050 int i;
1051 int x, y, wi, he; 1051 int x, y, wi, he;
1052  1052
1053 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 1053 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
1054 return; 1054 return;
1055 1055
1056 wi = font->fontwidth; 1056 wi = font->fontwidth;
1057 he = font->fontheight; 1057 he = font->fontheight;
1058 1058
1059 if (!CHAR_IN_FONT(c, font)) 1059 if (!CHAR_IN_FONT(c, font))
1060 return; 1060 return;
1061 1061
1062 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 1062 bg = ri->ri_devcmap[(attr >> 16) & 0xf];
1063 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 1063 fg = ri->ri_devcmap[(attr >> 24) & 0xf];
1064 x = ri->ri_xorigin + col * wi; 1064 x = ri->ri_xorigin + col * wi;
1065 y = ri->ri_yorigin + row * he; 1065 y = ri->ri_yorigin + row * he;
1066 1066
1067 data = WSFONT_GLYPH(c, font); 1067 data = WSFONT_GLYPH(c, font);
1068 1068
1069 ffb_ras_setbg(sc, bg); 1069 ffb_ras_setbg(sc, bg);
1070 ffb_ras_setfg(sc, fg); 1070 ffb_ras_setfg(sc, fg);
1071 ffb_ras_fifo_wait(sc, 4); 1071 ffb_ras_fifo_wait(sc, 4);
1072 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); 1072 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW);
1073 FBC_WRITE(sc, FFB_FBC_FONTXY, (y << 16) | x); 1073 FBC_WRITE(sc, FFB_FBC_FONTXY, (y << 16) | x);
1074 FBC_WRITE(sc, FFB_FBC_FONTW, wi); 1074 FBC_WRITE(sc, FFB_FBC_FONTW, wi);
1075 FBC_WRITE(sc, FFB_FBC_PPC, 1075 FBC_WRITE(sc, FFB_FBC_PPC,
1076 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |  1076 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |
1077 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |  1077 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |
1078 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); 1078 FBC_PPC_ABE_DIS | FBC_PPC_XS_WID);
1079 1079
1080 switch (font->stride) { 1080 switch (font->stride) {
1081 case 1: { 1081 case 1: {
1082 uint8_t *data8 = data; 1082 uint8_t *data8 = data;
1083 uint32_t reg; 1083 uint32_t reg;
1084 if (attr & WSATTR_UNDERLINE) {  1084 if (attr & WSATTR_UNDERLINE) {
1085 for (i = 0; i < he - 2; i++) { 1085 for (i = 0; i < he - 2; i++) {
1086 reg = *data8; 1086 reg = *data8;
1087 FBC_WRITE(sc, FFB_FBC_FONT, reg << 24); 1087 FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
1088 data8++; 1088 data8++;
1089 } 1089 }
1090 FBC_WRITE(sc, FFB_FBC_FONT, 0xff000000); 1090 FBC_WRITE(sc, FFB_FBC_FONT, 0xff000000);
1091 data8++; 1091 data8++;
1092 reg = *data8; 1092 reg = *data8;
1093 FBC_WRITE(sc, FFB_FBC_FONT, reg << 24); 1093 FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
1094 } else { 1094 } else {
1095 for (i = 0; i < he; i++) { 1095 for (i = 0; i < he; i++) {
1096 reg = *data8; 1096 reg = *data8;
1097 FBC_WRITE(sc, FFB_FBC_FONT, reg << 24); 1097 FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
1098 data8++; 1098 data8++;
1099 } 1099 }
1100 } 1100 }
1101 break; 1101 break;
1102 } 1102 }
1103 case 2: { 1103 case 2: {
1104 uint16_t *data16 = data; 1104 uint16_t *data16 = data;
1105 uint32_t reg; 1105 uint32_t reg;
1106 if (attr & WSATTR_UNDERLINE) {  1106 if (attr & WSATTR_UNDERLINE) {
1107 for (i = 0; i < he - 2; i++) { 1107 for (i = 0; i < he - 2; i++) {
1108 reg = *data16; 1108 reg = *data16;
1109 FBC_WRITE(sc, FFB_FBC_FONT, reg << 16); 1109 FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
1110 data16++; 1110 data16++;
1111 } 1111 }
1112 FBC_WRITE(sc, FFB_FBC_FONT, 0xffff0000); 1112 FBC_WRITE(sc, FFB_FBC_FONT, 0xffff0000);
1113 data16++; 1113 data16++;
1114 reg = *data16; 1114 reg = *data16;
1115 FBC_WRITE(sc, FFB_FBC_FONT, reg << 16); 1115 FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
1116 } else { 1116 } else {
1117 for (i = 0; i < he; i++) { 1117 for (i = 0; i < he; i++) {
1118 reg = *data16; 1118 reg = *data16;
1119 FBC_WRITE(sc, FFB_FBC_FONT, reg << 16); 1119 FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
1120 data16++; 1120 data16++;
1121 } 1121 }
1122 } 1122 }
1123 break; 1123 break;
1124 } 1124 }
1125 } 1125 }
1126} 1126}
1127 1127
1128/* alpha font */ 1128/* alpha font */
1129void 1129void
1130ffb_putchar_aa(void *cookie, int row, int col, u_int c, long attr) 1130ffb_putchar_aa(void *cookie, int row, int col, u_int c, long attr)
1131{ 1131{
1132 struct rasops_info *ri = cookie; 1132 struct rasops_info *ri = cookie;
1133 struct vcons_screen *scr = ri->ri_hw; 1133 struct vcons_screen *scr = ri->ri_hw;
1134 struct wsdisplay_font *font = PICK_FONT(ri, c); 1134 struct wsdisplay_font *font = PICK_FONT(ri, c);
1135 struct ffb_softc *sc = scr->scr_cookie; 1135 struct ffb_softc *sc = scr->scr_cookie;
1136 volatile uint32_t *dest, *ddest; 1136 volatile uint32_t *dest, *ddest;
1137 uint8_t *data8; 1137 uint8_t *data8;
1138 uint32_t fg, bg; 1138 uint32_t fg, bg;
1139 int i; 1139 int i;
1140 int x, y, wi, he; 1140 int x, y, wi, he;
1141 uint32_t alpha = 0x80; 1141 uint32_t alpha = 0x80;
1142 int j; 1142 int j;
1143  1143
1144 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 1144 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
1145 return; 1145 return;
1146 1146
1147 wi = font->fontwidth; 1147 wi = font->fontwidth;
1148 he = font->fontheight; 1148 he = font->fontheight;
1149 1149
1150 if (!CHAR_IN_FONT(c, font)) 1150 if (!CHAR_IN_FONT(c, font))
1151 return; 1151 return;
1152 1152
1153 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 1153 bg = ri->ri_devcmap[(attr >> 16) & 0xf];
1154 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 1154 fg = ri->ri_devcmap[(attr >> 24) & 0xf];
1155 x = ri->ri_xorigin + col * wi; 1155 x = ri->ri_xorigin + col * wi;
1156 y = ri->ri_yorigin + row * he; 1156 y = ri->ri_yorigin + row * he;
1157 1157
1158 data8 = WSFONT_GLYPH(c, font); 1158 data8 = WSFONT_GLYPH(c, font);
1159 1159
1160 /* first we erase the background */ 1160 /* first we erase the background */
1161 ffb_ras_fill(sc); 1161 ffb_ras_fill(sc);
1162 ffb_ras_setfg(sc, bg); 1162 ffb_ras_setfg(sc, bg);
1163 ffb_ras_fifo_wait(sc, 4); 1163 ffb_ras_fifo_wait(sc, 4);
1164 FBC_WRITE(sc, FFB_FBC_BY, y); 1164 FBC_WRITE(sc, FFB_FBC_BY, y);
1165 FBC_WRITE(sc, FFB_FBC_BX, x); 1165 FBC_WRITE(sc, FFB_FBC_BX, x);
1166 FBC_WRITE(sc, FFB_FBC_BH, he); 1166 FBC_WRITE(sc, FFB_FBC_BH, he);
1167 FBC_WRITE(sc, FFB_FBC_BW, wi); 1167 FBC_WRITE(sc, FFB_FBC_BW, wi);
1168 1168
1169 /* if we draw a space we're done */ 1169 /* if we draw a space we're done */
1170 if (c == ' ') goto out; 1170 if (c == ' ') goto out;
1171 1171
1172 /* now enable alpha blending */ 1172 /* now enable alpha blending */
1173 ffb_ras_setfg(sc, fg); 1173 ffb_ras_setfg(sc, fg);
1174 ffb_ras_fifo_wait(sc, 2); 1174 ffb_ras_fifo_wait(sc, 2);
1175 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); 1175 FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW);
1176 1176
1177 FBC_WRITE(sc, FFB_FBC_PPC, 1177 FBC_WRITE(sc, FFB_FBC_PPC,
1178 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |  1178 FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS |
1179 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |  1179 FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST |
1180 FBC_PPC_ABE_ENA | FBC_PPC_XS_VAR); 1180 FBC_PPC_ABE_ENA | FBC_PPC_XS_VAR);
1181 /* 1181 /*
1182 * we have to wait for both the rectangle drawing op above and the  1182 * we have to wait for both the rectangle drawing op above and the
1183 * FFB_FBC_PPC write to finish before mucking around in the SFB aperture 1183 * FFB_FBC_PPC write to finish before mucking around in the SFB aperture
1184 */ 1184 */
1185 ffb_ras_wait(sc); 1185 ffb_ras_wait(sc);
1186 1186
1187 /* ... and draw the character */ 1187 /* ... and draw the character */
1188 dest = sc->sc_sfb32 + (y << 11) + x; 1188 dest = sc->sc_sfb32 + (y << 11) + x;
1189 for (i = 0; i < he; i++) { 1189 for (i = 0; i < he; i++) {
1190 ddest = dest; 1190 ddest = dest;
1191 for (j = 0; j < wi; j++) { 1191 for (j = 0; j < wi; j++) {
1192 alpha = *data8; 1192 alpha = *data8;
1193 /* 1193 /*
1194 * We set the colour source to constant above so we only 1194 * We set the colour source to constant above so we only
1195 * have to write the alpha channel here and the colour 1195 * have to write the alpha channel here and the colour
1196 * comes from the FG register. It would be nice if we 1196 * comes from the FG register. It would be nice if we
1197 * could just use the SFB8X aperture and memcpy() the 1197 * could just use the SFB8X aperture and memcpy() the
1198 * alpha map line by line but for some strange reason 1198 * alpha map line by line but for some strange reason
1199 * that will take colour info from the framebuffer even 1199 * that will take colour info from the framebuffer even
1200 * if we set the FBC_PPC_CS_CONST bit above. 1200 * if we set the FBC_PPC_CS_CONST bit above.
1201 */ 1201 */
1202 *ddest = alpha << 24; 1202 *ddest = alpha << 24;
1203 data8++; 1203 data8++;
1204 ddest++; 1204 ddest++;
1205 } 1205 }
1206 dest += 2048; 1206 dest += 2048;
1207 } 1207 }
1208out: 1208out:
1209 /* check if we need to draw an underline */ 1209 /* check if we need to draw an underline */
1210 if (attr & WSATTR_UNDERLINE) { 1210 if (attr & WSATTR_UNDERLINE) {
1211 dest = sc->sc_sfb32 + ((y + he - 2) << 11) + x; 1211 dest = sc->sc_sfb32 + ((y + he - 2) << 11) + x;
1212 for (i = 0; i < wi; i++) { 1212 for (i = 0; i < wi; i++) {
1213 *dest = 0xa0000000; 1213 *dest = 0xa0000000;
1214 dest++; 1214 dest++;
1215 } 1215 }
1216 } 1216 }
1217} 1217}
1218 1218
1219int 1219int
1220ffb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp) 1220ffb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
1221{ 1221{
1222 if ((fg == 0) && (bg == 0)) 1222 if ((fg == 0) && (bg == 0))
1223 { 1223 {
1224 fg = WS_DEFAULT_FG; 1224 fg = WS_DEFAULT_FG;
1225 bg = WS_DEFAULT_BG; 1225 bg = WS_DEFAULT_BG;
1226 } 1226 }
1227 if (flags & WSATTR_REVERSE) { 1227 if (flags & WSATTR_REVERSE) {
1228 *attrp = (bg & 0xff) << 24 | (fg & 0xff) << 16; 1228 *attrp = (bg & 0xff) << 24 | (fg & 0xff) << 16;
1229 } else 1229 } else
1230 *attrp = (fg & 0xff) << 24 | (bg & 0xff) << 16; 1230 *attrp = (fg & 0xff) << 24 | (bg & 0xff) << 16;
1231 if (flags & WSATTR_UNDERLINE) 1231 if (flags & WSATTR_UNDERLINE)
1232 *attrp |= WSATTR_UNDERLINE; 1232 *attrp |= WSATTR_UNDERLINE;
1233 return 0; 1233 return 0;
1234} 1234}
1235 1235
1236void 1236void
1237ffb_init_screen(void *cookie, struct vcons_screen *scr, 1237ffb_init_screen(void *cookie, struct vcons_screen *scr,
1238 int existing, long *defattr) 1238 int existing, long *defattr)
1239{ 1239{
1240 struct ffb_softc *sc = cookie; 1240 struct ffb_softc *sc = cookie;
1241 struct rasops_info *ri = &scr->scr_ri; 1241 struct rasops_info *ri = &scr->scr_ri;
1242 1242
1243 ri->ri_depth = 32; 1243 ri->ri_depth = 32;
1244 ri->ri_width = sc->sc_width; 1244 ri->ri_width = sc->sc_width;
1245 ri->ri_height = sc->sc_height; 1245 ri->ri_height = sc->sc_height;
1246 ri->ri_stride = sc->sc_linebytes; 1246 ri->ri_stride = sc->sc_linebytes;
1247 ri->ri_flg = RI_CENTER | RI_ENABLE_ALPHA | RI_PREFER_ALPHA; 1247 ri->ri_flg = RI_CENTER | RI_ENABLE_ALPHA | RI_PREFER_ALPHA;
1248 1248
1249 /* 1249 /*
1250 * we can't accelerate copycols() so instead of falling back to 1250 * we can't accelerate copycols() so instead of falling back to
1251 * software use vcons' putchar() based implementation 1251 * software use vcons' putchar() based implementation
1252 */ 1252 */
1253 scr->scr_flags |= VCONS_NO_COPYCOLS | VCONS_LOADFONT; 1253 scr->scr_flags |= VCONS_NO_COPYCOLS | VCONS_LOADFONT;
1254 1254
1255#ifdef VCONS_DRAW_INTR 1255#ifdef VCONS_DRAW_INTR
1256 scr->scr_flags |= VCONS_DONT_READ; 1256 scr->scr_flags |= VCONS_DONT_READ;
1257#endif 1257#endif
1258 DPRINTF(("ffb_init_screen: addr: %08lx\n",(ulong)ri->ri_bits)); 1258 DPRINTF(("ffb_init_screen: addr: %08lx\n",(ulong)ri->ri_bits));
1259 1259
1260 /* explicitly request BGR in case the default changes */ 1260 /* explicitly request BGR in case the default changes */
1261 ri->ri_rnum = 8; 1261 ri->ri_rnum = 8;
1262 ri->ri_gnum = 8; 1262 ri->ri_gnum = 8;
1263 ri->ri_bnum = 8; 1263 ri->ri_bnum = 8;
1264 ri->ri_rpos = 0; 1264 ri->ri_rpos = 0;
1265 ri->ri_gpos = 8; 1265 ri->ri_gpos = 8;
1266 ri->ri_bpos = 16; 1266 ri->ri_bpos = 16;
1267 1267
1268 rasops_init(ri, 0, 0); 1268 rasops_init(ri, 0, 0);
1269 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, 1269 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
1270 sc->sc_width / ri->ri_font->fontwidth); 1270 sc->sc_width / ri->ri_font->fontwidth);
1271 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE |  1271 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE |
1272 WSSCREEN_REVERSE | WSSCREEN_RESIZE; 1272 WSSCREEN_REVERSE | WSSCREEN_RESIZE;
1273 1273
1274 /* enable acceleration */ 1274 /* enable acceleration */
1275 ri->ri_ops.copyrows = ffb_ras_copyrows; 1275 ri->ri_ops.copyrows = ffb_ras_copyrows;
1276 ri->ri_ops.eraserows = ffb_ras_eraserows; 1276 ri->ri_ops.eraserows = ffb_ras_eraserows;
1277 ri->ri_ops.erasecols = ffb_ras_erasecols; 1277 ri->ri_ops.erasecols = ffb_ras_erasecols;
1278 ri->ri_ops.cursor = ffb_cursor; 1278 ri->ri_ops.cursor = ffb_cursor;
1279 ri->ri_ops.allocattr = ffb_allocattr; 1279 ri->ri_ops.allocattr = ffb_allocattr;
1280 if (FONT_IS_ALPHA(ri->ri_font)) { 1280 if (FONT_IS_ALPHA(ri->ri_font)) {
1281 ri->ri_ops.putchar = ffb_putchar_aa; 1281 ri->ri_ops.putchar = ffb_putchar_aa;
1282 } else 1282 } else
1283 ri->ri_ops.putchar = ffb_putchar_mono; 1283 ri->ri_ops.putchar = ffb_putchar_mono;
1284} 1284}
1285 1285
1286/* I2C bitbanging */ 1286/* I2C bitbanging */
1287static void ffb_i2cbb_set_bits(void *cookie, uint32_t bits) 1287static void ffb_i2cbb_set_bits(void *cookie, uint32_t bits)
1288{ 1288{
1289 struct ffb_softc *sc = cookie; 1289 struct ffb_softc *sc = cookie;
1290 1290
1291 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_CFG_MPDATA); 1291 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_CFG_MPDATA);
1292 DAC_WRITE(sc, FFB_DAC_VALUE, bits); 1292 DAC_WRITE(sc, FFB_DAC_VALUE, bits);
1293} 1293}
1294 1294
1295static void ffb_i2cbb_set_dir(void *cookie, uint32_t dir) 1295static void ffb_i2cbb_set_dir(void *cookie, uint32_t dir)
1296{ 1296{
1297 /* Nothing to do */ 1297 /* Nothing to do */
1298} 1298}
1299 1299
1300static uint32_t ffb_i2cbb_read(void *cookie) 1300static uint32_t ffb_i2cbb_read(void *cookie)
1301{ 1301{
1302 struct ffb_softc *sc = cookie; 1302 struct ffb_softc *sc = cookie;
1303 uint32_t bits; 1303 uint32_t bits;
1304 1304
1305 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_CFG_MPSENSE); 1305 DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_CFG_MPSENSE);
1306 bits = DAC_READ(sc, FFB_DAC_VALUE); 1306 bits = DAC_READ(sc, FFB_DAC_VALUE);
1307 1307
1308 return bits; 1308 return bits;