Thu Aug 6 18:26:03 2009 UTC ()
make the tcx driver do something useful:
- attach a wsdisplay
- make it work with an S24
- accelerate scrolling and character drawing
This isn't quite finished yet, it works fine as a console but most things
X will need are not functional right now.


(macallan)
diff -r1.32 -r1.33 src/sys/dev/sbus/files.sbus
diff -r1.31 -r1.32 src/sys/dev/sbus/tcx.c
diff -r1.4 -r1.5 src/sys/dev/sbus/tcxreg.h

cvs diff -r1.32 -r1.33 src/sys/dev/sbus/files.sbus (expand / switch to unified diff)

--- src/sys/dev/sbus/files.sbus 2009/04/23 20:46:49 1.32
+++ src/sys/dev/sbus/files.sbus 2009/08/06 18:26:03 1.33
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: files.sbus,v 1.32 2009/04/23 20:46:49 macallan Exp $ 1# $NetBSD: files.sbus,v 1.33 2009/08/06 18:26:03 macallan Exp $
2# 2#
3# Config file and device description for machine-independent SBUS code. 3# Config file and device description for machine-independent SBUS code.
4# Included by ports that need it. 4# Included by ports that need it.
5 5
6device sbus { slot = -1, offset = -1 } 6device sbus { slot = -1, offset = -1 }
7#notyet:file dev/sbus/sbus.c sbus 7#notyet:file dev/sbus/sbus.c sbus
8 8
9# Sbus expander device 9# Sbus expander device
10device xbox {} 10device xbox {}
11attach xbox at sbus 11attach xbox at sbus
12attach sbus at xbox with sbus_xbox 12attach sbus at xbox with sbus_xbox
13file dev/sbus/xbox.c xbox 13file dev/sbus/xbox.c xbox
14 14
@@ -105,36 +105,37 @@ file dev/sbus/stp4020.c nell @@ -105,36 +105,37 @@ file dev/sbus/stp4020.c nell
105# 105#
106# Framebuffer devices (requires dev/sun/files.sun) 106# Framebuffer devices (requires dev/sun/files.sun)
107# 107#
108attach bwtwo at sbus with bwtwo_sbus 108attach bwtwo at sbus with bwtwo_sbus
109file dev/sbus/bwtwo_sbus.c bwtwo_sbus 109file dev/sbus/bwtwo_sbus.c bwtwo_sbus
110 110
111attach cgsix at sbus with cgsix_sbus 111attach cgsix at sbus with cgsix_sbus
112file dev/sbus/cgsix_sbus.c cgsix_sbus 112file dev/sbus/cgsix_sbus.c cgsix_sbus
113 113
114attach cgthree at sbus with cgthree_sbus 114attach cgthree at sbus with cgthree_sbus
115file dev/sbus/cgthree_sbus.c cgthree_sbus 115file dev/sbus/cgthree_sbus.c cgthree_sbus
116 116
117# framebuffer devices implemented only on SBus 117# framebuffer devices implemented only on SBus
118device tcx: bt_dac, fb, rasops8, rasops24 118device tcx: bt_dac, fb, rasops8, wsemuldisplaydev, vcons
119attach tcx at sbus 119attach tcx at sbus
120file dev/sbus/tcx.c tcx needs-flag 120file dev/sbus/tcx.c tcx needs-flag
121 121
122device zx: fb, rasops32, wsemuldisplaydev, vcons 122device zx: fb, rasops32, wsemuldisplaydev, vcons
123attach zx at sbus 123attach zx at sbus
124file dev/sbus/zx.c zx 124file dev/sbus/zx.c zx
125 125
126# Tadpole 3GX/3GS (P9100 -- P Nine One Zero Zero -> pnozz) 126# Tadpole 3GX/3GS (P9100 -- P Nine One Zero Zero -> pnozz)
127defflag opt_pnozz.h PNOZZ_DEBUG 127defflag opt_pnozz.h PNOZZ_DEBUG
 128defflag opt_pnozz.h PNOZZ_EMUL_CG3
128device pnozz: fb, rasops8, bt_dac, wsemuldisplaydev, vcons 129device pnozz: fb, rasops8, bt_dac, wsemuldisplaydev, vcons
129attach pnozz at sbus 130attach pnozz at sbus
130file dev/sbus/p9100.c pnozz needs-flag 131file dev/sbus/p9100.c pnozz needs-flag
131 132
132# SUNW,DBRI audio 133# SUNW,DBRI audio
133defflag opt_sbus_dbri.h DBRI_DEBUG 134defflag opt_sbus_dbri.h DBRI_DEBUG
134defflag opt_sbus_dbri.h DBRI_BIG_BUFFER DBRI_SPIN 135defflag opt_sbus_dbri.h DBRI_BIG_BUFFER DBRI_SPIN
135device dbri { }: audiobus, auconv, mulaw 136device dbri { }: audiobus, auconv, mulaw
136attach dbri at sbus 137attach dbri at sbus
137file dev/sbus/dbri.c dbri 138file dev/sbus/dbri.c dbri
138 139
139# an SBus frontend for genfb 140# an SBus frontend for genfb
140attach genfb at sbus with genfb_sbus : fb 141attach genfb at sbus with genfb_sbus : fb

cvs diff -r1.31 -r1.32 src/sys/dev/sbus/tcx.c (expand / switch to unified diff)

--- src/sys/dev/sbus/tcx.c 2009/05/12 14:43:59 1.31
+++ src/sys/dev/sbus/tcx.c 2009/08/06 18:26:03 1.32
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tcx.c,v 1.31 2009/05/12 14:43:59 cegger Exp $ */ 1/* $NetBSD: tcx.c,v 1.32 2009/08/06 18:26:03 macallan Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996,1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996,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.
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * color display (TCX) driver. 33 * color display (TCX) driver.
34 * 34 *
35 * Does not handle interrupts, even though they can occur. 35 * Does not handle interrupts, even though they can occur.
36 * 36 *
37 * XXX should defer colormap updates to vertical retrace interrupts 37 * XXX should defer colormap updates to vertical retrace interrupts
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.31 2009/05/12 14:43:59 cegger Exp $"); 41__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.32 2009/08/06 18:26:03 macallan Exp $");
42 42
43/* 43/*
44 * define for cg8 emulation on S24 (24-bit version of tcx) for the SS5; 44 * define for cg8 emulation on S24 (24-bit version of tcx) for the SS5;
45 * it is bypassed on the 8-bit version (onboard framebuffer for SS4) 45 * it is bypassed on the 8-bit version (onboard framebuffer for SS4)
46 */ 46 */
47#undef TCX_CG8 47#undef TCX_CG8
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/systm.h> 50#include <sys/systm.h>
51#include <sys/buf.h> 51#include <sys/buf.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>
@@ -62,42 +62,78 @@ __KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.31 @@ -62,42 +62,78 @@ __KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.31
62#endif 62#endif
63 63
64#include <sys/bus.h> 64#include <sys/bus.h>
65#include <machine/autoconf.h> 65#include <machine/autoconf.h>
66 66
67#include <dev/sun/fbio.h> 67#include <dev/sun/fbio.h>
68#include <dev/sun/fbvar.h> 68#include <dev/sun/fbvar.h>
69#include <dev/sun/btreg.h> 69#include <dev/sun/btreg.h>
70#include <dev/sun/btvar.h> 70#include <dev/sun/btvar.h>
71 71
72#include <dev/sbus/sbusvar.h> 72#include <dev/sbus/sbusvar.h>
73#include <dev/sbus/tcxreg.h> 73#include <dev/sbus/tcxreg.h>
74 74
 75#include <dev/wscons/wsdisplayvar.h>
 76#include <dev/wscons/wsconsio.h>
 77#include <dev/wsfont/wsfont.h>
 78#include <dev/rasops/rasops.h>
 79
 80#include <dev/wscons/wsdisplay_vconsvar.h>
 81
 82#include "opt_wsemul.h"
 83
75/* per-display variables */ 84/* per-display variables */
76struct tcx_softc { 85struct tcx_softc {
77 struct device sc_dev; /* base device */ 86 struct device sc_dev; /* base device */
78 struct sbusdev sc_sd; /* sbus device */ 87 struct sbusdev sc_sd; /* sbus device */
79 struct fbdevice sc_fb; /* frame buffer device */ 88 struct fbdevice sc_fb; /* frame buffer device */
80 bus_space_tag_t sc_bustag; 89 bus_space_tag_t sc_bustag;
81 struct openprom_addr sc_physadr[TCX_NREG];/* phys addr of h/w */ 90 struct openprom_addr sc_physadr[TCX_NREG];/* phys addr of h/w */
82 91
83 volatile struct bt_regs *sc_bt; /* Brooktree registers */ 92 bus_space_handle_t sc_bt; /* Brooktree registers */
84 volatile struct tcx_thc *sc_thc;/* THC registers */ 93 bus_space_handle_t sc_thc; /* THC registers */
85#ifdef TCX_CG8 94 uint8_t *sc_fbaddr; /* framebuffer */
86 volatile ulong *sc_cplane; /* framebuffer with control planes */ 95 uint64_t *sc_rblit; /* blitspace */
87#endif 96 uint64_t *sc_rstip; /* stipple space */
 97
88 short sc_8bit; /* true if 8-bit hardware */ 98 short sc_8bit; /* true if 8-bit hardware */
89 short sc_blanked; /* true if blanked */ 99 short sc_blanked; /* true if blanked */
90 union bt_cmap sc_cmap; /* Brooktree color map */ 100 u_char sc_cmap_red[256];
 101 u_char sc_cmap_green[256];
 102 u_char sc_cmap_blue[256];
 103 int sc_mode, sc_bg;
 104 struct vcons_data vd;
 105};
 106
 107static struct vcons_screen tcx_console_screen;
 108
 109extern const u_char rasops_cmap[768];
 110
 111struct wsscreen_descr tcx_defscreendesc = {
 112 "default",
 113 0, 0,
 114 NULL,
 115 8, 16,
 116 WSSCREEN_WSCOLORS,
 117};
 118
 119const struct wsscreen_descr *_tcx_scrlist[] = {
 120 &tcx_defscreendesc,
 121 /* XXX other formats, graphics screen? */
 122};
 123
 124struct wsscreen_list tcx_screenlist = {
 125 sizeof(_tcx_scrlist) / sizeof(struct wsscreen_descr *),
 126 _tcx_scrlist
91}; 127};
92 128
93/* 129/*
94 * The S24 provides the framebuffer RAM mapped in three ways: 130 * The S24 provides the framebuffer RAM mapped in three ways:
95 * 26 bits per pixel, in 32-bit words; the low-order 24 bits are 131 * 26 bits per pixel, in 32-bit words; the low-order 24 bits are
96 * blue, green, and red values, and the other two bits select the 132 * blue, green, and red values, and the other two bits select the
97 * display modes, per pixel); 133 * display modes, per pixel);
98 * 24 bits per pixel, in 32-bit words; the high-order byte reads as 134 * 24 bits per pixel, in 32-bit words; the high-order byte reads as
99 * zero, and is ignored on writes (so the mode bits cannot be altered); 135 * zero, and is ignored on writes (so the mode bits cannot be altered);
100 * 8 bits per pixel, unpadded; writes to this space do not modify the 136 * 8 bits per pixel, unpadded; writes to this space do not modify the
101 * other 18 bits. 137 * other 18 bits.
102 */ 138 */
103#define TCX_CTL_8_MAPPED 0x00000000 /* 8 bits, uses color map */ 139#define TCX_CTL_8_MAPPED 0x00000000 /* 8 bits, uses color map */
@@ -124,26 +160,46 @@ const struct cdevsw tcx_cdevsw = { @@ -124,26 +160,46 @@ const struct cdevsw tcx_cdevsw = {
124 tcxopen, tcxclose, noread, nowrite, tcxioctl, 160 tcxopen, tcxclose, noread, nowrite, tcxioctl,
125 nostop, notty, nopoll, tcxmmap, nokqfilter, 161 nostop, notty, nopoll, tcxmmap, nokqfilter,
126}; 162};
127 163
128/* frame buffer generic driver */ 164/* frame buffer generic driver */
129static struct fbdriver tcx_fbdriver = { 165static struct fbdriver tcx_fbdriver = {
130 tcx_unblank, tcxopen, tcxclose, tcxioctl, nopoll, tcxmmap, 166 tcx_unblank, tcxopen, tcxclose, tcxioctl, nopoll, tcxmmap,
131 nokqfilter 167 nokqfilter
132}; 168};
133 169
134static void tcx_reset(struct tcx_softc *); 170static void tcx_reset(struct tcx_softc *);
135static void tcx_loadcmap(struct tcx_softc *, int, int); 171static void tcx_loadcmap(struct tcx_softc *, int, int);
136 172
 173static int tcx_ioctl(void *, void *, u_long, void *, int, struct lwp *);
 174static paddr_t tcx_mmap(void *, void *, off_t, int);
 175
 176static void tcx_init_screen(void *, struct vcons_screen *, int, long *);
 177static void tcx_clearscreen(struct tcx_softc *);
 178static void tcx_copyrows(void *, int, int, int);
 179static void tcx_eraserows(void *, int, int, long);
 180static void tcx_putchar(void *, int, int, u_int, long);
 181
 182struct wsdisplay_accessops tcx_accessops = {
 183 tcx_ioctl,
 184 tcx_mmap,
 185 NULL, /* vcons_alloc_screen */
 186 NULL, /* vcons_free_screen */
 187 NULL, /* vcons_show_screen */
 188 NULL, /* load_font */
 189 NULL, /* polls */
 190 NULL, /* scroll */
 191};
 192
137#define OBPNAME "SUNW,tcx" 193#define OBPNAME "SUNW,tcx"
138 194
139#ifdef TCX_CG8 195#ifdef TCX_CG8
140/* 196/*
141 * For CG8 emulation, we map the 32-bit-deep framebuffer at an offset of 197 * For CG8 emulation, we map the 32-bit-deep framebuffer at an offset of
142 * 256K; the cg8 space begins with a mono overlay plane and an overlay 198 * 256K; the cg8 space begins with a mono overlay plane and an overlay
143 * enable plane (128K bytes each, 1 bit per pixel), immediately followed 199 * enable plane (128K bytes each, 1 bit per pixel), immediately followed
144 * by the color planes, 32 bits per pixel. We also map just the 32-bit 200 * by the color planes, 32 bits per pixel. We also map just the 32-bit
145 * framebuffer at 0x04000000 (TCX_USER_RAM_COMPAT), for compatibility 201 * framebuffer at 0x04000000 (TCX_USER_RAM_COMPAT), for compatibility
146 * with the cg8 driver. 202 * with the cg8 driver.
147 */ 203 */
148#define TCX_CG8OVERLAY (256 * 1024) 204#define TCX_CG8OVERLAY (256 * 1024)
149#define TCX_SIZE_DFB32 (1152 * 900 * 4) /* max size of the framebuffer */ 205#define TCX_SIZE_DFB32 (1152 * 900 * 4) /* max size of the framebuffer */
@@ -158,181 +214,208 @@ tcxmatch(device_t parent, cfdata_t cf, v @@ -158,181 +214,208 @@ tcxmatch(device_t parent, cfdata_t cf, v
158 struct sbus_attach_args *sa = aux; 214 struct sbus_attach_args *sa = aux;
159 215
160 return (strcmp(sa->sa_name, OBPNAME) == 0); 216 return (strcmp(sa->sa_name, OBPNAME) == 0);
161} 217}
162 218
163/* 219/*
164 * Attach a display. 220 * Attach a display.
165 */ 221 */
166void 222void
167tcxattach(device_t parent, device_t self, void *args) 223tcxattach(device_t parent, device_t self, void *args)
168{ 224{
169 struct tcx_softc *sc = device_private(self); 225 struct tcx_softc *sc = device_private(self);
170 struct sbus_attach_args *sa = args; 226 struct sbus_attach_args *sa = args;
 227 struct wsemuldisplaydev_attach_args aa;
 228 struct rasops_info *ri;
 229 unsigned long defattr;
171 int node, ramsize; 230 int node, ramsize;
172 volatile struct bt_regs *bt; 
173 struct fbdevice *fb = &sc->sc_fb; 231 struct fbdevice *fb = &sc->sc_fb;
174 bus_space_handle_t bh; 232 bus_space_handle_t bh;
175 int isconsole; 233 int isconsole, i, j;
 234 uint32_t confreg;
176 235
177 sc->sc_bustag = sa->sa_bustag; 236 sc->sc_bustag = sa->sa_bustag;
178 node = sa->sa_node; 237 node = sa->sa_node;
179 238
180 fb->fb_driver = &tcx_fbdriver; 239 fb->fb_driver = &tcx_fbdriver;
181 fb->fb_device = &sc->sc_dev; 240 fb->fb_device = &sc->sc_dev;
182 /* Mask out invalid flags from the user. */ 241 /* Mask out invalid flags from the user. */
183 fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK; 242 fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK;
184 /* 243 /*
185 * The onboard framebuffer on the SS4 supports only 8-bit mode; 244 * The onboard framebuffer on the SS4 supports only 8-bit mode;
186 * it can be distinguished from the S24 card for the SS5 by the 245 * it can be distinguished from the S24 card for the SS5 by the
187 * presence of the "tcx-8-bit" attribute on the SS4 version. 246 * presence of the "tcx-8-bit" attribute on the SS4 version.
188 */ 247 */
189 sc->sc_8bit = node_has_property(node, "tcx-8-bit"); 248 sc->sc_8bit = node_has_property(node, "tcx-8-bit");
190#ifdef TCX_CG8 249 fb->fb_type.fb_depth = 8;
191 if (sc->sc_8bit) { 250 fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
192#endif 
193 /* 
194 * cg8 emulation is either not compiled in or not supported 
195 * on this hardware. Report values for the 8-bit framebuffer 
196 * so cg3 emulation works. (If this hardware supports 
197 * 24-bit mode, the 24-bit framebuffer will also be available) 
198 */ 
199 fb->fb_type.fb_depth = 8; 
200 fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node); 
201 251
202 ramsize = fb->fb_type.fb_height * fb->fb_linebytes; 252 if (sc->sc_8bit) {
203#ifdef TCX_CG8 253 printf(" {8bit only TCX)");
 254 ramsize = 1024 * 1024;
 255 /* XXX - fix THC and TEC offsets */
 256 sc->sc_physadr[TCX_REG_TEC].oa_base += 0x1000;
 257 sc->sc_physadr[TCX_REG_THC].oa_base += 0x1000;
204 } else { 258 } else {
205 /* 259 printf(" (S24)\n");
206 * for cg8 emulation, unconditionally report the depth as 260 ramsize = 4 * 1024 * 1024;
207 * 32 bits, but use the height and width reported by the 
208 * boot prom. cg8 users want to see the full size of 
209 * overlay planes plus color planes included in the 
210 * reported framebuffer size. 
211 */ 
212 fb->fb_type.fb_depth = 32; 
213 fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node); 
214 fb->fb_linebytes = 
215 (fb->fb_type.fb_width * fb->fb_type.fb_depth) / 8; 
216 ramsize = TCX_CG8OVERLAY + 
217 (fb->fb_type.fb_height * fb->fb_linebytes); 
218 } 261 }
219#endif 262
220 fb->fb_type.fb_cmsize = 256; 263 fb->fb_type.fb_cmsize = 256;
221 fb->fb_type.fb_size = ramsize; 264 fb->fb_type.fb_size = ramsize;
222 printf(": %s, %d x %d", OBPNAME, 265 printf(": %s, %d x %d", OBPNAME,
223 fb->fb_type.fb_width, 266 fb->fb_type.fb_width,
224 fb->fb_type.fb_height); 267 fb->fb_type.fb_height);
225#ifdef TCX_CG8 
226 /* 
227 * if cg8 emulation is enabled, say so; but if hardware can't 
228 * emulate cg8, explain that instead 
229 */ 
230 printf( (sc->sc_8bit)? 
231 " (8-bit only)" : 
232 " (emulating cg8)"); 
233#endif 
234 268
235 /* 269 fb->fb_type.fb_type = FBTYPE_SUNTCX;
236 * XXX - should be set to FBTYPE_TCX. 
237 * XXX For CG3 emulation to work in current (96/6) X11 servers, 
238 * XXX `fbtype' must point to an "unregocnised" entry. 
239 */ 
240#ifdef TCX_CG8 
241 if (sc->sc_8bit) { 
242 fb->fb_type.fb_type = FBTYPE_RESERVED3; 
243 } else { 
244 fb->fb_type.fb_type = FBTYPE_MEMCOLOR; 
245 } 
246#else 
247 fb->fb_type.fb_type = FBTYPE_RESERVED3; 
248#endif 
249 270
250 271
251 if (sa->sa_nreg != TCX_NREG) { 272 if (sa->sa_nreg != TCX_NREG) {
252 printf("%s: only %d register sets\n", 273 printf("%s: only %d register sets\n",
253 device_xname(self), sa->sa_nreg); 274 device_xname(self), sa->sa_nreg);
254 return; 275 return;
255 } 276 }
256 memcpy(sc->sc_physadr, sa->sa_reg, 277 memcpy(sc->sc_physadr, sa->sa_reg,
257 sa->sa_nreg * sizeof(struct openprom_addr)); 278 sa->sa_nreg * sizeof(struct openprom_addr));
258 279
259 /* XXX - fix THC and TEC offsets */ 
260 sc->sc_physadr[TCX_REG_TEC].oa_base += 0x1000; 
261 sc->sc_physadr[TCX_REG_THC].oa_base += 0x1000; 
262 
263 /* Map the register banks we care about */ 280 /* Map the register banks we care about */
264 if (sbus_bus_map(sa->sa_bustag, 281 if (sbus_bus_map(sa->sa_bustag,
265 sc->sc_physadr[TCX_REG_THC].oa_space, 282 sc->sc_physadr[TCX_REG_THC].oa_space,
266 sc->sc_physadr[TCX_REG_THC].oa_base, 283 sc->sc_physadr[TCX_REG_THC].oa_base,
267 sizeof (struct tcx_thc), 284 0x1000,
268 BUS_SPACE_MAP_LINEAR, &bh) != 0) { 285 BUS_SPACE_MAP_LINEAR, &sc->sc_thc) != 0) {
269 printf("tcxattach: cannot map thc registers\n"); 286 printf("tcxattach: cannot map thc registers\n");
270 return; 287 return;
271 } 288 }
272 sc->sc_thc = (volatile struct tcx_thc *) 
273 bus_space_vaddr(sa->sa_bustag, bh); 
274 289
275 if (sbus_bus_map(sa->sa_bustag, 290 if (sbus_bus_map(sa->sa_bustag,
276 sc->sc_physadr[TCX_REG_CMAP].oa_space, 291 sc->sc_physadr[TCX_REG_CMAP].oa_space,
277 sc->sc_physadr[TCX_REG_CMAP].oa_base, 292 sc->sc_physadr[TCX_REG_CMAP].oa_base,
278 sizeof (struct bt_regs), 293 0x1000,
279 BUS_SPACE_MAP_LINEAR, &bh) != 0) { 294 BUS_SPACE_MAP_LINEAR, &sc->sc_bt) != 0) {
280 printf("tcxattach: cannot map bt registers\n"); 295 printf("tcxattach: cannot map bt registers\n");
281 return; 296 return;
282 } 297 }
283 sc->sc_bt = bt = (volatile struct bt_regs *) 
284 bus_space_vaddr(sa->sa_bustag, bh); 
285 298
286#ifdef TCX_CG8 299 /* map the 8bit dumb FB for the console */
287 if (!sc->sc_8bit) { 300 if (sbus_bus_map(sa->sa_bustag,
288 if (sbus_bus_map(sa->sa_bustag, 301 sc->sc_physadr[TCX_REG_DFB8].oa_space,
289 sc->sc_physadr[TCX_REG_RDFB32].oa_space, 302 sc->sc_physadr[TCX_REG_DFB8].oa_base,
290 sc->sc_physadr[TCX_REG_RDFB32].oa_base, 303 1024 * 1024,
291 TCX_SIZE_DFB32, 
292 BUS_SPACE_MAP_LINEAR, 304 BUS_SPACE_MAP_LINEAR,
293 &bh) != 0) { 305 &bh) != 0) {
294 printf("tcxattach: cannot map control planes\n"); 306 printf("tcxattach: cannot map framebuffer\n");
295 return; 307 return;
296 } 
297 sc->sc_cplane = (volatile ulong *)bh; 
298 } 308 }
299#endif 309 sc->sc_fbaddr = bus_space_vaddr(sa->sa_bustag, bh);
 310
 311 /* RBLIT space */
 312 if (sbus_bus_map(sa->sa_bustag,
 313 sc->sc_physadr[TCX_REG_RBLIT].oa_space,
 314 sc->sc_physadr[TCX_REG_RBLIT].oa_base,
 315 8 * 1024 * 1024,
 316 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
 317 &bh) != 0) {
 318 printf("tcxattach: cannot map RBLIT space\n");
 319 return;
 320 }
 321 sc->sc_rblit = bus_space_vaddr(sa->sa_bustag, bh);
 322
 323 /* RSTIP space */
 324 if (sbus_bus_map(sa->sa_bustag,
 325 sc->sc_physadr[TCX_REG_RSTIP].oa_space,
 326 sc->sc_physadr[TCX_REG_RSTIP].oa_base,
 327 8 * 1024 * 1024,
 328 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
 329 &bh) != 0) {
 330 printf("tcxattach: cannot map RSTIP space\n");
 331 return;
 332 }
 333 sc->sc_rstip = bus_space_vaddr(sa->sa_bustag, bh);
300 334
301 isconsole = fb_is_console(node); 335 isconsole = fb_is_console(node);
302 336
 337 confreg = bus_space_read_4(sa->sa_bustag, sc->sc_thc, THC_CONFIG);
303 printf(", id %d, rev %d, sense %d", 338 printf(", id %d, rev %d, sense %d",
304 (sc->sc_thc->thc_config & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT, 339 (confreg & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
305 (sc->sc_thc->thc_config & THC_CFG_REV) >> THC_CFG_REV_SHIFT, 340 (confreg & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
306 (sc->sc_thc->thc_config & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT 341 (confreg & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
307 ); 342 );
308 343
309 /* reset cursor & frame buffer controls */ 344 /* reset cursor & frame buffer controls */
310 tcx_reset(sc); 345 tcx_reset(sc);
311 346
312 /* Initialize the default color map. */ 347 /* Initialize the default color map. */
313 bt_initcmap(&sc->sc_cmap, 256); 348 j = 0;
 349 for (i = 0; i < 256; i++) {
 350
 351 sc->sc_cmap_red[i] = rasops_cmap[j];
 352 sc->sc_cmap_green[i] = rasops_cmap[j + 1];
 353 sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
 354 j += 3;
 355 }
314 tcx_loadcmap(sc, 0, 256); 356 tcx_loadcmap(sc, 0, 256);
315 357
316 /* enable video */ 358 /* enable video */
317 sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN; 359 confreg = bus_space_read_4(sa->sa_bustag, sc->sc_thc, THC_MISC);
 360 confreg |= THC_MISC_VIDEN;
 361 bus_space_write_4(sa->sa_bustag, sc->sc_thc, THC_MISC, confreg);
318 362
319 if (isconsole) { 363 if (isconsole) {
320 printf(" (console)\n"); 364 printf(" (console)\n");
321 } else 365 } else
322 printf("\n"); 366 printf("\n");
323 367
 368 bus_space_write_4(sa->sa_bustag, sc->sc_bt, DAC_ADDRESS, 0);
 369 printf("DAC ID: %02x %02x\n",
 370 bus_space_read_1(sa->sa_bustag, sc->sc_bt, DAC_CONTROL_1),
 371 bus_space_read_1(sa->sa_bustag, sc->sc_bt, DAC_CONTROL_1));
324 sbus_establish(&sc->sc_sd, &sc->sc_dev); 372 sbus_establish(&sc->sc_sd, &sc->sc_dev);
325 fb_attach(&sc->sc_fb, isconsole); 373 fb_attach(&sc->sc_fb, isconsole);
 374
 375 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
 376 wsfont_init();
 377
 378 vcons_init(&sc->vd, sc, &tcx_defscreendesc, &tcx_accessops);
 379 sc->vd.init_screen = tcx_init_screen;
 380
 381 vcons_init_screen(&sc->vd, &tcx_console_screen, 1, &defattr);
 382 tcx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
 383
 384 sc->sc_bg = (defattr >> 16) & 0xff;
 385 tcx_clearscreen(sc);
 386
 387 ri = &tcx_console_screen.scr_ri;
 388
 389 tcx_defscreendesc.nrows = ri->ri_rows;
 390 tcx_defscreendesc.ncols = ri->ri_cols;
 391 tcx_defscreendesc.textops = &ri->ri_ops;
 392 tcx_defscreendesc.capabilities = ri->ri_caps;
 393
 394 if(isconsole) {
 395 wsdisplay_cnattach(&tcx_defscreendesc, ri, 0, 0, defattr);
 396 }
 397
 398 aa.console = isconsole;
 399 aa.scrdata = &tcx_screenlist;
 400 aa.accessops = &tcx_accessops;
 401 aa.accesscookie = &sc->vd;
 402
 403 config_found(self, &aa, wsemuldisplaydevprint);
 404 /*
 405 * we need to do this again - something overwrites a handful
 406 * palette registers and we end up with white in reg. 0
 407 */
 408 tcx_loadcmap(sc, 0, 256);
326} 409}
327 410
328#ifdef TCX_CG8 411#ifdef TCX_CG8
329/* 412/*
330 * keep track of the number of opens, so we can switch to 24-bit mode 413 * keep track of the number of opens, so we can switch to 24-bit mode
331 * when the device is first opened, and return to 8-bit mode on the 414 * when the device is first opened, and return to 8-bit mode on the
332 * last close. (stolen from cgfourteen driver...) There can only be 415 * last close. (stolen from cgfourteen driver...) There can only be
333 * one TCX per system, so we only need one flag. 416 * one TCX per system, so we only need one flag.
334 */ 417 */
335static int tcx_opens = 0; 418static int tcx_opens = 0;
336#endif 419#endif
337 420
338int 421int
@@ -397,146 +480,143 @@ tcxclose(dev_t dev, int flags, int mode, @@ -397,146 +480,143 @@ tcxclose(dev_t dev, int flags, int mode,
397 cptr = sc->sc_cplane; 480 cptr = sc->sc_cplane;
398 while (--i >= 0) 481 while (--i >= 0)
399 *cptr++ &= TCX_CTL_PIXELMASK; 482 *cptr++ &= TCX_CTL_PIXELMASK;
400 } 483 }
401 } 484 }
402#endif 485#endif
403 return (0); 486 return (0);
404} 487}
405 488
406int 489int
407tcxioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 490tcxioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
408{ 491{
409 struct tcx_softc *sc = device_lookup_private(&tcx_cd, minor(dev)); 492 struct tcx_softc *sc = device_lookup_private(&tcx_cd, minor(dev));
410 int error; 493 //int error;
411 494
412 switch (cmd) { 495 switch (cmd) {
413 496
414 case FBIOGTYPE: 497 case FBIOGTYPE:
415 *(struct fbtype *)data = sc->sc_fb.fb_type; 498 *(struct fbtype *)data = sc->sc_fb.fb_type;
416 break; 499 break;
417 500
418 case FBIOGATTR: 501 case FBIOGATTR:
419#define fba ((struct fbgattr *)data) 502#define fba ((struct fbgattr *)data)
420 fba->real_type = sc->sc_fb.fb_type.fb_type; 503 fba->real_type = sc->sc_fb.fb_type.fb_type;
421 fba->owner = 0; /* XXX ??? */ 504 fba->owner = 0; /* XXX ??? */
422 fba->fbtype = sc->sc_fb.fb_type; 505 fba->fbtype = sc->sc_fb.fb_type;
423 fba->sattr.flags = 0; 506 fba->sattr.flags = 0;
424 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; 507 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
425 fba->sattr.dev_specific[0] = -1; 508 fba->sattr.dev_specific[0] = -1;
426 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; 509 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
427 fba->emu_types[1] = FBTYPE_SUN3COLOR; 510 fba->emu_types[1] = FBTYPE_SUN3COLOR;
428 fba->emu_types[2] = -1; 511 fba->emu_types[2] = -1;
429#undef fba 512#undef fba
430 break; 513 break;
431 514#if 0
432 case FBIOGETCMAP: 515 case FBIOGETCMAP:
433#define p ((struct fbcmap *)data) 516#define p ((struct fbcmap *)data)
434 return (bt_getcmap(p, &sc->sc_cmap, 256, 1)); 517 return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
435 518
436 case FBIOPUTCMAP: 519 case FBIOPUTCMAP:
437 /* copy to software map */ 520 /* copy to software map */
438#ifdef TCX_CG8 521#ifdef TCX_CG8
439 if (!sc->sc_8bit) { 522 if (!sc->sc_8bit) {
440 /* 523 /*
441 * cg8 has extra bits in high-order byte of the index 524 * cg8 has extra bits in high-order byte of the index
442 * that bt_putcmap doesn't recognize 525 * that bt_putcmap doesn't recognize
443 */ 526 */
444 p->index &= 0xffffff; 527 p->index &= 0xffffff;
445 } 528 }
446#endif 529#endif
447 error = bt_putcmap(p, &sc->sc_cmap, 256, 1); 530 error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
448 if (error) 531 if (error)
449 return (error); 532 return (error);
450 /* now blast them into the chip */ 533 /* now blast them into the chip */
451 /* XXX should use retrace interrupt */ 534 /* XXX should use retrace interrupt */
452 tcx_loadcmap(sc, p->index, p->count); 535 tcx_loadcmap(sc, p->index, p->count);
453#undef p 536#undef p
454 break; 537 break;
455 538#endif
456 case FBIOGVIDEO: 539 case FBIOGVIDEO:
457 *(int *)data = sc->sc_blanked; 540 *(int *)data = sc->sc_blanked;
458 break; 541 break;
459 542
460 case FBIOSVIDEO: 543 case FBIOSVIDEO:
461 if (*(int *)data) 544 if (*(int *)data)
462 tcx_unblank(&sc->sc_dev); 545 tcx_unblank(&sc->sc_dev);
463 else if (!sc->sc_blanked) { 546 else if (!sc->sc_blanked) {
464 sc->sc_blanked = 1; 547 sc->sc_blanked = 1;
465 sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN; 548 //sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
466 /* Put monitor in `power-saving mode' */ 549 /* Put monitor in `power-saving mode' */
467 sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE; 550 //sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE;
468 sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE; 551 //sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE;
469 } 552 }
470 break; 553 break;
471 554
472 default: 555 default:
473#ifdef DEBUG 556#ifdef DEBUG
474 log(LOG_NOTICE, "tcxioctl(0x%lx) (%s[%d])\n", cmd, 557 log(LOG_NOTICE, "tcxioctl(0x%lx) (%s[%d])\n", cmd,
475 l->l_proc->p_comm, l->l_proc->p_pid); 558 l->l_proc->p_comm, l->l_proc->p_pid);
476#endif 559#endif
477 return (ENOTTY); 560 return (ENOTTY);
478 } 561 }
479 return (0); 562 return (0);
480} 563}
481 564
482/* 565/*
483 * Clean up hardware state (e.g., after bootup or after X crashes). 566 * Clean up hardware state (e.g., after bootup or after X crashes).
484 */ 567 */
485static void 568static void
486tcx_reset(struct tcx_softc *sc) 569tcx_reset(struct tcx_softc *sc)
487{ 570{
488 volatile struct bt_regs *bt; 
489 571
490 /* Enable cursor in Brooktree DAC. */ 572 /* Enable cursor in Brooktree DAC. */
491 bt = sc->sc_bt; 573 /* TODO: bus_spacify */
492 bt->bt_addr = 0x06 << 24; 574// bt->bt_addr = 0x06 << 24;
493 bt->bt_ctrl |= 0x03 << 24; 575// bt->bt_ctrl |= 0x03 << 24;
494} 576}
495 577
496/* 578/*
497 * Load a subset of the current (new) colormap into the color DAC. 579 * Load a subset of the current (new) colormap into the color DAC.
498 */ 580 */
499static void 581static void
500tcx_loadcmap(struct tcx_softc *sc, int start, int ncolors) 582tcx_loadcmap(struct tcx_softc *sc, int start, int ncolors)
501{ 583{
502 volatile struct bt_regs *bt; 584 int i;
503 u_int *ip, i; 585
504 int count; 586 for (i = 0; i < ncolors; i++) {
505 587 bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS,
506 ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */ 588 (start + i) << 24);
507 count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3; 589 bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_FB_LUT,
508 bt = sc->sc_bt; 590 sc->sc_cmap_red[i + start] << 24);
509 bt->bt_addr = BT_D4M4(start) << 24; 591 bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_FB_LUT,
510 while (--count >= 0) { 592 sc->sc_cmap_green[i + start] << 24);
511 i = *ip++; 593 bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_FB_LUT,
512 /* hardware that makes one want to pound boards with hammers */ 594 sc->sc_cmap_blue[i + start] << 24);
513 bt->bt_cmap = i; 
514 bt->bt_cmap = i << 8; 
515 bt->bt_cmap = i << 16; 
516 bt->bt_cmap = i << 24; 
517 } 595 }
 596 bus_space_write_4(sc->sc_bustag, sc->sc_bt, DAC_ADDRESS, 0);
518} 597}
519 598
520static void 599static void
521tcx_unblank(device_t dev) 600tcx_unblank(device_t dev)
522{ 601{
523 struct tcx_softc *sc = device_private(dev); 602 struct tcx_softc *sc = device_private(dev);
524 603
525 if (sc->sc_blanked) { 604 if (sc->sc_blanked) {
 605
526 sc->sc_blanked = 0; 606 sc->sc_blanked = 0;
527 sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE; 607 //sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE;
528 sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE; 608 //sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE;
529 sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN; 609 //sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
530 } 610 }
531} 611}
532 612
533/* 613/*
534 * Base addresses at which users can mmap() the various pieces of a tcx. 614 * Base addresses at which users can mmap() the various pieces of a tcx.
535 */ 615 */
536#define TCX_USER_RAM 0x00000000 616#define TCX_USER_RAM 0x00000000
537#define TCX_USER_RAM24 0x01000000 617#define TCX_USER_RAM24 0x01000000
538#define TCX_USER_RAM_COMPAT 0x04000000 /* cg3 emulation */ 618#define TCX_USER_RAM_COMPAT 0x04000000 /* cg3 emulation */
539#define TCX_USER_STIP 0x10000000 619#define TCX_USER_STIP 0x10000000
540#define TCX_USER_BLIT 0x20000000 620#define TCX_USER_BLIT 0x20000000
541#define TCX_USER_RDFB32 0x28000000 621#define TCX_USER_RDFB32 0x28000000
542#define TCX_USER_RSTIP 0x30000000 622#define TCX_USER_RSTIP 0x30000000
@@ -571,27 +651,27 @@ tcxmmap(dev_t dev, off_t off, int prot) @@ -571,27 +651,27 @@ tcxmmap(dev_t dev, off_t off, int prot)
571 u_int u, sz; 651 u_int u, sz;
572 static struct mmo mmo[] = { 652 static struct mmo mmo[] = {
573 { TCX_USER_RAM, 0, TCX_REG_DFB8 }, 653 { TCX_USER_RAM, 0, TCX_REG_DFB8 },
574 { TCX_USER_RAM24, 0, TCX_REG_DFB24 }, 654 { TCX_USER_RAM24, 0, TCX_REG_DFB24 },
575 { TCX_USER_RAM_COMPAT, 0, TCX_REG_DFB8 }, 655 { TCX_USER_RAM_COMPAT, 0, TCX_REG_DFB8 },
576 656
577 { TCX_USER_STIP, 1, TCX_REG_STIP }, 657 { TCX_USER_STIP, 1, TCX_REG_STIP },
578 { TCX_USER_BLIT, 1, TCX_REG_BLIT }, 658 { TCX_USER_BLIT, 1, TCX_REG_BLIT },
579 { TCX_USER_RDFB32, 0, TCX_REG_RDFB32 }, 659 { TCX_USER_RDFB32, 0, TCX_REG_RDFB32 },
580 { TCX_USER_RSTIP, 1, TCX_REG_RSTIP }, 660 { TCX_USER_RSTIP, 1, TCX_REG_RSTIP },
581 { TCX_USER_RBLIT, 1, TCX_REG_RBLIT }, 661 { TCX_USER_RBLIT, 1, TCX_REG_RBLIT },
582 { TCX_USER_TEC, 1, TCX_REG_TEC }, 662 { TCX_USER_TEC, 1, TCX_REG_TEC },
583 { TCX_USER_BTREGS, 8192 /* XXX */, TCX_REG_CMAP }, 663 { TCX_USER_BTREGS, 8192 /* XXX */, TCX_REG_CMAP },
584 { TCX_USER_THC, sizeof(struct tcx_thc), TCX_REG_THC }, 664 { TCX_USER_THC, 0x1000, TCX_REG_THC },
585 { TCX_USER_DHC, 1, TCX_REG_DHC }, 665 { TCX_USER_DHC, 1, TCX_REG_DHC },
586 { TCX_USER_ALT, 1, TCX_REG_ALT }, 666 { TCX_USER_ALT, 1, TCX_REG_ALT },
587 { TCX_USER_ROM, 65536, TCX_REG_ROM }, 667 { TCX_USER_ROM, 65536, TCX_REG_ROM },
588 }; 668 };
589#define NMMO (sizeof mmo / sizeof *mmo) 669#define NMMO (sizeof mmo / sizeof *mmo)
590#ifdef TCX_CG8 670#ifdef TCX_CG8
591 /* 671 /*
592 * alternate mapping for CG8 emulation: 672 * alternate mapping for CG8 emulation:
593 * map part of the 8-bit-deep framebuffer into the cg8 overlay 673 * map part of the 8-bit-deep framebuffer into the cg8 overlay
594 * space, just so there's something there, and map the 32-bit-deep 674 * space, just so there's something there, and map the 32-bit-deep
595 * framebuffer where cg8 users expect to find it. 675 * framebuffer where cg8 users expect to find it.
596 */ 676 */
597 static struct mmo mmo_cg8[] = { 677 static struct mmo mmo_cg8[] = {
@@ -649,13 +729,351 @@ tcxmmap(dev_t dev, off_t off, int prot) @@ -649,13 +729,351 @@ tcxmmap(dev_t dev, off_t off, int prot)
649 } 729 }
650 } 730 }
651 if (u < sz) { 731 if (u < sz) {
652 return (bus_space_mmap(sc->sc_bustag, 732 return (bus_space_mmap(sc->sc_bustag,
653 BUS_ADDR(rr[mo->mo_bank].oa_space, 733 BUS_ADDR(rr[mo->mo_bank].oa_space,
654 rr[mo->mo_bank].oa_base), 734 rr[mo->mo_bank].oa_base),
655 u, 735 u,
656 prot, 736 prot,
657 BUS_SPACE_MAP_LINEAR)); 737 BUS_SPACE_MAP_LINEAR));
658 } 738 }
659 } 739 }
660 return (-1); 740 return (-1);
661} 741}
 742
 743int
 744tcx_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
 745 struct lwp *l)
 746{
 747 struct vcons_data *vd = v;
 748 struct tcx_softc *sc = vd->cookie;
 749 struct wsdisplay_fbinfo *wdf;
 750 struct vcons_screen *ms = vd->active;
 751
 752 switch (cmd) {
 753 case WSDISPLAYIO_GTYPE:
 754 *(u_int *)data = WSDISPLAY_TYPE_SUNTCX;
 755 return 0;
 756
 757#if 0
 758 case FBIOGVIDEO:
 759 case WSDISPLAYIO_GVIDEO:
 760 *(int *)data = tcx_get_video(sc);
 761 return 0;
 762
 763 case WSDISPLAYIO_SVIDEO:
 764 case FBIOSVIDEO:
 765 tcx_set_video(sc, *(int *)data);
 766 return 0;
 767#endif
 768 case WSDISPLAYIO_GINFO:
 769 wdf = (void *)data;
 770 wdf->height = ms->scr_ri.ri_height;
 771 wdf->width = ms->scr_ri.ri_width;
 772 wdf->depth = ms->scr_ri.ri_depth;
 773 wdf->cmsize = 256;
 774 return 0;
 775#if 0
 776 case WSDISPLAYIO_GETCMAP:
 777 return tcx_getcmap(sc, (struct wsdisplay_cmap *)data);
 778
 779 case WSDISPLAYIO_PUTCMAP:
 780 return tcx_putcmap(sc, (struct wsdisplay_cmap *)data);
 781#endif
 782 case WSDISPLAYIO_SMODE:
 783 {
 784 int new_mode = *(int*)data;
 785 if (new_mode != sc->sc_mode)
 786 {
 787 sc->sc_mode = new_mode;
 788 if (new_mode == WSDISPLAYIO_MODE_EMUL)
 789 {
 790#if 0
 791 tcxloadcmap(sc, 0, 256);
 792 tcx_clearscreen(sc);
 793#endif
 794 vcons_redraw_screen(ms);
 795 }
 796 }
 797 }
 798 }
 799 return EPASSTHROUGH;
 800}
 801
 802static paddr_t
 803tcx_mmap(void *v, void *vs, off_t offset, int prot)
 804{
 805#if 0
 806 struct vcons_data *vd = v;
 807 struct tcx_softc *sc = vd->cookie;
 808 paddr_t pa;
 809
 810 /* 'regular' framebuffer mmap()ing */
 811 if (offset < sc->sc_fb_psize) {
 812 pa = bus_space_mmap(sc->sc_bustag, sc->sc_fb_paddr + offset, 0,
 813 prot, BUS_SPACE_MAP_LINEAR);
 814 return pa;
 815 }
 816
 817 if ((offset >= sc->sc_fb_paddr) && (offset < (sc->sc_fb_paddr +
 818 sc->sc_fb_psize))) {
 819 pa = bus_space_mmap(sc->sc_bustag, offset, 0, prot,
 820 BUS_SPACE_MAP_LINEAR);
 821 return pa;
 822 }
 823
 824 if ((offset >= sc->sc_ctl_paddr) && (offset < (sc->sc_ctl_paddr +
 825 sc->sc_ctl_psize))) {
 826 pa = bus_space_mmap(sc->sc_bustag, offset, 0, prot,
 827 BUS_SPACE_MAP_LINEAR);
 828 return pa;
 829 }
 830#endif
 831 return -1;
 832}
 833
 834static void
 835tcx_init_screen(void *cookie, struct vcons_screen *scr,
 836 int existing, long *defattr)
 837{
 838 struct tcx_softc *sc = cookie;
 839 struct rasops_info *ri = &scr->scr_ri;
 840
 841 ri->ri_depth = 8;
 842 ri->ri_width = sc->sc_fb.fb_type.fb_width;
 843 ri->ri_height = sc->sc_fb.fb_type.fb_height;
 844 ri->ri_stride = sc->sc_fb.fb_linebytes;
 845 ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
 846
 847 ri->ri_bits = sc->sc_fbaddr;
 848
 849 rasops_init(ri, ri->ri_height/8, ri->ri_width/8);
 850 ri->ri_caps = WSSCREEN_WSCOLORS;
 851 rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
 852 ri->ri_width / ri->ri_font->fontwidth);
 853
 854 /* enable acceleration */
 855 ri->ri_ops.copyrows = tcx_copyrows;
 856 ri->ri_ops.eraserows = tcx_eraserows;
 857 ri->ri_ops.putchar = tcx_putchar;
 858#if 0
 859 ri->ri_ops.cursor = tcx_cursor;
 860 ri->ri_ops.copycols = tcx_copycols;
 861 ri->ri_ops.erasecols = tcx_erasecols;
 862#endif
 863}
 864
 865static void
 866tcx_clearscreen(struct tcx_softc *sc)
 867{
 868 uint64_t bg = ((uint64_t)sc->sc_bg << 32) | 0xffffffffLL;
 869 int i;
 870
 871 for (i = 0; i < 1024 * 1024; i += 32)
 872 sc->sc_rstip[i] = bg;
 873}
 874
 875static void
 876tcx_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
 877{
 878 struct rasops_info *ri = cookie;
 879 struct vcons_screen *scr = ri->ri_hw;
 880 struct tcx_softc *sc = scr->scr_cookie;
 881 int i, last, first, len, dest, leftover;
 882
 883 i = ri->ri_width * ri->ri_font->fontheight * nrows;
 884 len = i & 0xffffe0;
 885 leftover = i & 0x1f;
 886 if (srcrow < dstrow) {
 887 /* we must go bottom to top */
 888 first = ri->ri_width *
 889 (ri->ri_font->fontheight * srcrow + ri->ri_yorigin);
 890 last = first + len;
 891 dest = ri->ri_width *
 892 (ri->ri_font->fontheight * dstrow + ri->ri_yorigin) + len;
 893 if (leftover > 0) {
 894 sc->sc_rblit[dest + 32] =
 895 (uint64_t)((leftover - 1) << 24) |
 896 (uint64_t)(i + 32);
 897 }
 898 for (i = last; i >= first; i -= 32) {
 899 sc->sc_rblit[dest] = 0x300000001f000000LL | (uint64_t)i;
 900 dest -= 32;
 901 }
 902 } else {
 903 /* top to bottom */
 904 first = ri->ri_width *
 905 (ri->ri_font->fontheight * srcrow + ri->ri_yorigin);
 906 dest = ri->ri_width *
 907 (ri->ri_font->fontheight * dstrow + ri->ri_yorigin);
 908 last = first + len;
 909 for (i = first; i <= last; i+= 32) {
 910 sc->sc_rblit[dest] = 0x300000001f000000LL | (uint64_t)i;
 911 dest += 32;
 912 }
 913 if (leftover > 0) {
 914 sc->sc_rblit[dest] =
 915 (uint64_t)((leftover - 1) << 24) | (uint64_t)i;
 916 }
 917 }
 918}
 919
 920static void
 921tcx_eraserows(void *cookie, int start, int nrows, long attr)
 922{
 923 struct rasops_info *ri = cookie;
 924 struct vcons_screen *scr = ri->ri_hw;
 925 struct tcx_softc *sc = scr->scr_cookie;
 926 uint64_t temp;
 927 int i, last, first, len, leftover;
 928
 929 i = ri->ri_width * ri->ri_font->fontheight * nrows;
 930 len = i & 0xffffe0;
 931 leftover = i & 0x1f;
 932 first = ri->ri_width *
 933 (ri->ri_font->fontheight * start + ri->ri_yorigin);
 934 last = first + len;
 935 temp = 0x30000000ffffffffLL |
 936 ((uint64_t)ri->ri_devcmap[(attr >> 16) & 0xff] << 32);
 937
 938 for (i = first; i <= last; i+= 32)
 939 sc->sc_rblit[i] = temp;
 940
 941 if (leftover > 0) {
 942 temp &= 0xffffffffffffffffLL << (32 - leftover);
 943 sc->sc_rblit[i] = temp;
 944 }
 945}
 946/*
 947 * The stipple engine is 100% retarded. All drawing operations have to start
 948 * at 32 pixel boundaries so we'll have to deal with characters being split.
 949 */
 950
 951static void
 952tcx_putchar(void *cookie, int row, int col, u_int c, long attr)
 953{
 954 struct rasops_info *ri = cookie;
 955 struct vcons_screen *scr = ri->ri_hw;
 956 struct tcx_softc *sc = scr->scr_cookie;
 957 uint64_t bg, fg, temp, mask;
 958 int addr, i, uc, shift;
 959 uint32_t fmask;
 960 uint8_t *cdata;
 961 uint16_t *wdata;
 962
 963 addr = ri->ri_xorigin +
 964 col * ri->ri_font->fontwidth +
 965 (ri->ri_yorigin + row * ri->ri_font->fontheight) * ri->ri_width;
 966
 967 /* check if the character is crossing a 32 pixel boundary */
 968 if ((addr & 0xffffe0) ==
 969 ((addr + ri->ri_font->fontwidth - 1) & 0xffffe0)) {
 970 /* phew, not split */
 971 shift = addr & 0x1f;
 972 addr &= 0xffffe0;
 973 fmask = 0xffffffff >> (32 - ri->ri_font->fontwidth);
 974 fmask = fmask << (32 - ri->ri_font->fontwidth - shift);
 975 mask = fmask;
 976 bg = 0x3000000000000000LL |
 977 ((uint64_t)ri->ri_devcmap[(attr >> 16) & 0xff] &
 978 0xff) << 32;
 979 bg |= mask;
 980 temp = 0x3000000000000000LL |
 981 ((uint64_t)ri->ri_devcmap[(attr >> 24) & 0xff] & 0xff) <<
 982 32;
 983 uc = c - ri->ri_font->firstchar;
 984 cdata = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
 985
 986 if (ri->ri_font->fontwidth < 9) {
 987 /* byte by byte */
 988 for (i = 0; i < ri->ri_font->fontheight; i++) {
 989 sc->sc_rstip[addr] = bg;
 990 if (*cdata != 0) {
 991 if (shift > 24) {
 992 fg = (uint64_t)*cdata >>
 993 (shift - 24);
 994 } else {
 995 fg = (uint64_t)*cdata <<
 996 (24 - shift);
 997 }
 998 sc->sc_rstip[addr] = fg | temp;
 999 }
 1000 cdata++;
 1001 addr += ri->ri_width;
 1002 }
 1003 } else if (ri->ri_font->fontwidth < 17) {
 1004 /* short by short */
 1005 wdata = (uint16_t *)cdata;
 1006 for (i = 0; i < ri->ri_font->fontheight; i++) {
 1007 sc->sc_rstip[addr] = bg;
 1008 if (*wdata != 0) {
 1009 if (shift > 16) {
 1010 fg = temp | (uint64_t)*wdata >>
 1011 (shift - 16);
 1012 } else {
 1013 fg = temp | (uint64_t)*wdata <<
 1014 (16 - shift);
 1015 }
 1016 sc->sc_rstip[addr] = fg;
 1017 }
 1018 wdata++;
 1019 addr += ri->ri_width;
 1020 }
 1021 }
 1022 } else {
 1023 /* and now the split case ( man this hardware is dumb ) */
 1024 uint64_t bgr, maskr, fgr;
 1025 uint32_t bork;
 1026
 1027 shift = addr & 0x1f;
 1028 addr &= 0xffffe0;
 1029 mask = 0xffffffff >> shift;
 1030 maskr = (uint64_t)(0xffffffffUL <<
 1031 (32 - (ri->ri_font->fontwidth + shift - 32)));
 1032 bg = 0x3000000000000000LL |
 1033 ((uint64_t)ri->ri_devcmap[(attr >> 16) & 0xff] &
 1034 0xff) << 32;
 1035 bgr = bg | maskr;
 1036 bg |= mask;
 1037 temp = 0x3000000000000000LL |
 1038 ((uint64_t)ri->ri_devcmap[(attr >> 24) & 0xff] & 0xff) <<
 1039 32;
 1040
 1041 uc = c - ri->ri_font->firstchar;
 1042 cdata = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
 1043
 1044 if (ri->ri_font->fontwidth < 9) {
 1045 /* byte by byte */
 1046 for (i = 0; i < ri->ri_font->fontheight; i++) {
 1047 sc->sc_rstip[addr] = bg;
 1048 sc->sc_rstip[addr + 32] = bgr;
 1049 bork = *cdata;
 1050 if (bork != 0) {
 1051 fg = (uint64_t)bork >> (shift - 24);
 1052 sc->sc_rstip[addr] = fg | temp;
 1053 fgr = (uint64_t)(bork << (52 - shift));
 1054 sc->sc_rstip[addr] = fgr | temp;
 1055 }
 1056 cdata++;
 1057 addr += ri->ri_width;
 1058 }
 1059 } else if (ri->ri_font->fontwidth < 17) {
 1060 /* short by short */
 1061 wdata = (uint16_t *)cdata;
 1062 for (i = 0; i < ri->ri_font->fontheight; i++) {
 1063 sc->sc_rstip[addr] = bg;
 1064 sc->sc_rstip[addr + 32] = bgr;
 1065 bork = *wdata;
 1066 if (bork != 0) {
 1067 fg = (uint64_t)bork >> (shift - 16);
 1068 sc->sc_rstip[addr] = fg | temp;
 1069 fgr = (uint64_t)(bork << (48 - shift));
 1070 sc->sc_rstip[addr + 32] = fgr | temp;
 1071 }
 1072 wdata++;
 1073 addr += ri->ri_width;
 1074 }
 1075 }
 1076
 1077 }
 1078}
 1079

cvs diff -r1.4 -r1.5 src/sys/dev/sbus/tcxreg.h (expand / switch to unified diff)

--- src/sys/dev/sbus/tcxreg.h 2008/04/28 20:23:57 1.4
+++ src/sys/dev/sbus/tcxreg.h 2009/08/06 18:26:03 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tcxreg.h,v 1.4 2008/04/28 20:23:57 martin Exp $ */ 1/* $NetBSD: tcxreg.h,v 1.5 2009/08/06 18:26:03 macallan Exp $ */
2/* 2/*
3 * Copyright (c) 1996 The NetBSD Foundation, Inc. 3 * Copyright (c) 1996 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to The NetBSD Foundation 6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Paul Kranenburg. 7 * by Paul Kranenburg.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -54,43 +54,42 @@ @@ -54,43 +54,42 @@
54#define TCX_REG_TEC 7 54#define TCX_REG_TEC 7
55#define TCX_REG_CMAP 8 55#define TCX_REG_CMAP 8
56#define TCX_REG_THC 9 56#define TCX_REG_THC 9
57#define TCX_REG_ROM 10 57#define TCX_REG_ROM 10
58#define TCX_REG_DHC 11 58#define TCX_REG_DHC 11
59#define TCX_REG_ALT 12 59#define TCX_REG_ALT 12
60 60
61#define TCX_NREG 13 61#define TCX_NREG 13
62 62
63 63
64/* 64/*
65 * The layout of the THC. 65 * The layout of the THC.
66 */ 66 */
67struct tcx_thc { 
68 u_int thc_config; 
69 u_int thc_xxx1[31]; 
70 u_int thc_sensebus; 
71 u_int thc_xxx2[3]; 
72 u_int thc_delay; 
73 u_int thc_strapping; 
74 u_int thc_xxx3[1]; 
75 u_int thc_linecount; 
76 u_int thc_xxx4[478]; 
77 u_int thc_hcmisc; 
78 u_int thc_xxx5[56]; 
79 u_int thc_cursoraddr; 
80 u_int thc_cursorAdata[32]; 
81 u_int thc_cursorBdata[32]; 
82 67
83}; 68#define THC_CONFIG 0x00000000
 69#define THC_SENSEBUS 0x00000080
 70#define THC_DELAY 0x00000090
 71#define THC_STRAPPING 0x00000094
 72#define THC_LINECOUNTER 0x0000009c
 73#define THC_HSYNC_START 0x000000a0
 74#define THC_HSYNC_END 0x000000a4
 75#define THC_HDISP_START 0x000000a8
 76#define THC_HDISP_VSYNC 0x000000ac
 77#define THC_HDISP_END 0x000000b0
 78#define THC_MISC 0x00000818
 79#define THC_CURSOR_POS 0x000008fc
 80#define THC_CURSOR_1 0x00000900 /* bitmap bit 1 */
 81#define THC_CURSOR_0 0x00000980 /* bitmap bit 0 */
 82
84/* bits in thc_config ??? */ 83/* bits in thc_config ??? */
85#define THC_CFG_FBID 0xf0000000 /* id mask */ 84#define THC_CFG_FBID 0xf0000000 /* id mask */
86#define THC_CFG_FBID_SHIFT 28 85#define THC_CFG_FBID_SHIFT 28
87#define THC_CFG_SENSE 0x07000000 /* sense mask */ 86#define THC_CFG_SENSE 0x07000000 /* sense mask */
88#define THC_CFG_SENSE_SHIFT 24 87#define THC_CFG_SENSE_SHIFT 24
89#define THC_CFG_REV 0x00f00000 /* revision mask */ 88#define THC_CFG_REV 0x00f00000 /* revision mask */
90#define THC_CFG_REV_SHIFT 20 89#define THC_CFG_REV_SHIFT 20
91#define THC_CFG_RST 0x00008000 /* reset */ 90#define THC_CFG_RST 0x00008000 /* reset */
92 91
93/* bits in thc_hcmisc */ 92/* bits in thc_hcmisc */
94#define THC_MISC_OPENFLG 0x80000000 /* open flag (what's that?) */ 93#define THC_MISC_OPENFLG 0x80000000 /* open flag (what's that?) */
95#define THC_MISC_SWERR_EN 0x20000000 /* enable SW error interrupt */ 94#define THC_MISC_SWERR_EN 0x20000000 /* enable SW error interrupt */
96#define THC_MISC_VSYNC_LEVEL 0x08000000 /* vsync level when disabled */ 95#define THC_MISC_VSYNC_LEVEL 0x08000000 /* vsync level when disabled */
@@ -131,13 +130,25 @@ struct tcx_tec { @@ -131,13 +130,25 @@ struct tcx_tec {
131 u_int tec_hcmisc; /* */ 130 u_int tec_hcmisc; /* */
132 u_int tec_linecount; /* */ 131 u_int tec_linecount; /* */
133 u_int tec_hss; /* */ 132 u_int tec_hss; /* */
134 u_int tec_hse; /* */ 133 u_int tec_hse; /* */
135 u_int tec_hds; /* */ 134 u_int tec_hds; /* */
136 u_int tec_hsedvs; /* */ 135 u_int tec_hsedvs; /* */
137 u_int tec_hde; /* */ 136 u_int tec_hde; /* */
138 u_int tec_vss; /* */ 137 u_int tec_vss; /* */
139 u_int tec_vse; /* */ 138 u_int tec_vse; /* */
140 u_int tec_vds; /* */ 139 u_int tec_vds; /* */
141 u_int tec_vde; /* */ 140 u_int tec_vde; /* */
142}; 141};
143 142
 143/* DAC registers */
 144#define DAC_ADDRESS 0x00000000
 145#define DAC_FB_LUT 0x00000004 /* palette / gamma table */
 146#define DAC_CONTROL_1 0x00000008
 147#define DAC_CURSOR_LUT 0x0000000c /* cursor sprite colours */
 148#define DAC_CONTROL_2 0x00000018
 149
 150#define DAC_C1_ID 0
 151#define DAC_C1_REVISION 1
 152#define DAC_C1_READ_MASK 4
 153#define DAC_C1_BLINK_MASK 5
 154#define DAC_C1_CONTROL_0 6