1 /* $NetBSD: cgtwo.c,v 1.53 2007/03/04 06:00:43 christos Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * from: @(#)cgthree.c 8.2 (Berkeley) 10/30/93
44 * color display (cgtwo) driver.
46 * Does not handle interrupts, even though they can occur.
48 * XXX should defer colormap updates to vertical retrace interrupts
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: cgtwo.c,v 1.53 2007/03/04 06:00:43 christos Exp $");
54 #include <sys/param.h>
55 #include <sys/systm.h>
57 #include <sys/device.h>
58 #include <sys/ioctl.h>
59 #include <sys/malloc.h>
64 #include <uvm/uvm_extern.h>
66 #include <machine/autoconf.h>
68 #include <dev/sun/fbio.h>
69 #include <dev/sun/fbvar.h>
71 #include <dev/vme/vmevar.h>
73 #include <machine/eeprom.h>
74 #include <machine/cgtworeg.h>
77 /* per-display variables */
79 struct device sc_dev
; /* base device */
80 struct fbdevice sc_fb
; /* frame buffer device */
82 vme_chipset_tag_t sc_ct
;
83 bus_space_tag_t sc_bt
;
84 volatile struct cg2statusreg
*sc_reg
; /* CG2 control registers */
85 volatile u_short
*sc_cmap
;
86 #define sc_redmap(sc) ((sc)->sc_cmap)
87 #define sc_greenmap(sc) ((sc)->sc_cmap + CG2_CMSIZE)
88 #define sc_bluemap(sc) ((sc)->sc_cmap + 2 * CG2_CMSIZE)
91 /* autoconfiguration driver */
92 static int cgtwomatch(struct device
*, struct cfdata
*, void *);
93 static void cgtwoattach(struct device
*, struct device
*, void *);
94 static void cgtwounblank(struct device
*);
95 int cgtwogetcmap(struct cgtwo_softc
*, struct fbcmap
*);
96 int cgtwoputcmap(struct cgtwo_softc
*, struct fbcmap
*);
98 CFATTACH_DECL(cgtwo
, sizeof(struct cgtwo_softc
),
99 cgtwomatch
, cgtwoattach
, NULL
, NULL
);
101 extern struct cfdriver cgtwo_cd
;
103 dev_type_open(cgtwoopen
);
104 dev_type_ioctl(cgtwoioctl
);
105 dev_type_mmap(cgtwommap
);
107 const struct cdevsw cgtwo_cdevsw
= {
108 cgtwoopen
, nullclose
, noread
, nowrite
, cgtwoioctl
,
109 nostop
, notty
, nopoll
, cgtwommap
, nokqfilter
,
112 /* frame buffer generic driver */
113 static struct fbdriver cgtwofbdriver
= {
114 cgtwounblank
, cgtwoopen
, nullclose
, cgtwoioctl
, nopoll
, cgtwommap
,
122 cgtwomatch(struct device
*parent
, struct cfdata
*cf
, void *aux
)
124 struct vme_attach_args
*va
= aux
;
125 vme_chipset_tag_t ct
= va
->va_vct
;
129 * Mask out invalid flags from the user.
131 cf
->cf_flags
&= FB_USERMASK
;
133 mod
= 0x3d; /* VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA */
134 if (vme_probe(ct
, va
->r
[0].offset
+ CG2_CTLREG_OFF
, 2, mod
, VME_D16
,
143 * Attach a display. We need to notice if it is the console, too.
146 cgtwoattach(struct device
*parent
, struct device
*self
, void *aux
)
148 struct vme_attach_args
*va
= aux
;
149 vme_chipset_tag_t ct
= va
->va_vct
;
151 bus_space_handle_t bh
;
154 struct cgtwo_softc
*sc
= device_private(self
);
155 struct fbdevice
*fb
= &sc
->sc_fb
;
156 struct eeprom
*eep
= (struct eeprom
*)eeprom_va
;
160 fb
->fb_driver
= &cgtwofbdriver
;
161 fb
->fb_device
= &sc
->sc_dev
;
162 fb
->fb_type
.fb_type
= FBTYPE_SUN2COLOR
;
163 fb
->fb_flags
= device_cfdata(&sc
->sc_dev
)->cf_flags
;
165 fb
->fb_type
.fb_depth
= 8;
166 fb_setsize_eeprom(fb
, fb
->fb_type
.fb_depth
, 1152, 900);
168 fb
->fb_type
.fb_cmsize
= 256;
169 fb
->fb_type
.fb_size
= roundup(CG2_MAPPED_SIZE
, PAGE_SIZE
);
170 printf(": cgtwo, %d x %d",
171 fb
->fb_type
.fb_width
, fb
->fb_type
.fb_height
);
174 * When the ROM has mapped in a cgtwo display, the address
175 * maps only the video RAM, so in any case we have to map the
176 * registers ourselves. We only need the video RAM if we are
177 * going to print characters via rconsole.
179 sc
->sc_paddr
= va
->r
[0].offset
;
180 mod
= 0x3d; /* VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA */
182 if (vme_space_map(ct
, sc
->sc_paddr
+ CG2_ROPMEM_OFF
+
183 offsetof(struct cg2fb
, status
.reg
),
184 sizeof(struct cg2statusreg
), mod
, VME_D16
, 0,
185 &bt
, &bh
, &resc
) != 0)
186 panic("cgtwo: vme_map status");
188 sc
->sc_reg
= (volatile struct cg2statusreg
*)bh
; /* XXX */
190 if (vme_space_map(ct
, sc
->sc_paddr
+ CG2_ROPMEM_OFF
+
191 offsetof(struct cg2fb
, redmap
[0]),
192 3 * CG2_CMSIZE
, mod
, VME_D16
, 0,
193 &bt
, &bh
, &resc
) != 0)
194 panic("cgtwo: vme_map cmap");
195 sc
->sc_cmap
= (volatile u_short
*)bh
; /* XXX */
198 * Assume this is the console if there's no eeprom info
201 if (eep
== NULL
|| eep
->eeConsole
== EE_CONS_COLOR
)
202 isconsole
= fb_is_console(0);
207 if (vme_space_map(ct
, sc
->sc_paddr
+ CG2_PIXMAP_OFF
,
208 CG2_PIXMAP_SIZE
, mod
, VME_D16
, 0,
209 &bt
, &bh
, &resc
) != 0)
210 panic("cgtwo: vme_map pixels");
212 fb
->fb_pixels
= (void *)bh
; /* XXX */
213 printf(" (console)\n");
220 fb_attach(fb
, isconsole
);
224 cgtwoopen(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
226 int unit
= minor(dev
);
228 if (device_lookup(&cgtwo_cd
, unit
) == NULL
)
234 cgtwoioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
236 register struct cgtwo_softc
*sc
= device_lookup_private(&cgtwo_cd
,
238 register struct fbgattr
*fba
;
243 *(struct fbtype
*)data
= sc
->sc_fb
.fb_type
;
247 fba
= (struct fbgattr
*)data
;
248 fba
->real_type
= sc
->sc_fb
.fb_type
.fb_type
;
249 fba
->owner
= 0; /* XXX ??? */
250 fba
->fbtype
= sc
->sc_fb
.fb_type
;
251 fba
->sattr
.flags
= 0;
252 fba
->sattr
.emu_type
= sc
->sc_fb
.fb_type
.fb_type
;
253 fba
->sattr
.dev_specific
[0] = -1;
254 fba
->emu_types
[0] = sc
->sc_fb
.fb_type
.fb_type
;
255 fba
->emu_types
[1] = -1;
259 return cgtwogetcmap(sc
, (struct fbcmap
*) data
);
262 return cgtwoputcmap(sc
, (struct fbcmap
*) data
);
265 *(int *)data
= sc
->sc_reg
->video_enab
;
269 sc
->sc_reg
->video_enab
= (*(int*)data
) & 1;
279 * Undo the effect of an FBIOSVIDEO that turns the video off.
282 cgtwounblank(struct device
*dev
)
284 struct cgtwo_softc
*sc
= device_private(dev
);
285 sc
->sc_reg
->video_enab
= 1;
291 cgtwogetcmap(struct cgtwo_softc
*sc
, struct fbcmap
*cmap
)
293 u_char red
[CG2_CMSIZE
], green
[CG2_CMSIZE
], blue
[CG2_CMSIZE
];
294 int error
, start
, count
, ecount
;
296 register volatile u_short
*p
;
300 ecount
= start
+ count
;
301 if (start
>= CG2_CMSIZE
|| count
> CG2_CMSIZE
- start
)
304 /* XXX - Wait for retrace? */
306 /* Copy hardware to local arrays. */
307 p
= &sc_redmap(sc
)[start
];
308 for (i
= start
; i
< ecount
; i
++)
310 p
= &sc_greenmap(sc
)[start
];
311 for (i
= start
; i
< ecount
; i
++)
313 p
= &sc_bluemap(sc
)[start
];
314 for (i
= start
; i
< ecount
; i
++)
317 /* Copy local arrays to user space. */
318 if ((error
= copyout(red
+ start
, cmap
->red
, count
)) != 0)
320 if ((error
= copyout(green
+ start
, cmap
->green
, count
)) != 0)
322 if ((error
= copyout(blue
+ start
, cmap
->blue
, count
)) != 0)
331 cgtwoputcmap(struct cgtwo_softc
*sc
, struct fbcmap
*cmap
)
333 u_char red
[CG2_CMSIZE
], green
[CG2_CMSIZE
], blue
[CG2_CMSIZE
];
335 u_int start
, count
, ecount
;
337 register volatile u_short
*p
;
341 ecount
= start
+ count
;
342 if (start
>= CG2_CMSIZE
|| count
> CG2_CMSIZE
- start
)
345 /* Copy from user space to local arrays. */
346 if ((error
= copyin(cmap
->red
, red
+ start
, count
)) != 0)
348 if ((error
= copyin(cmap
->green
, green
+ start
, count
)) != 0)
350 if ((error
= copyin(cmap
->blue
, blue
+ start
, count
)) != 0)
353 /* XXX - Wait for retrace? */
355 /* Copy from local arrays to hardware. */
356 p
= &sc_redmap(sc
)[start
];
357 for (i
= start
; i
< ecount
; i
++)
359 p
= &sc_greenmap(sc
)[start
];
360 for (i
= start
; i
< ecount
; i
++)
362 p
= &sc_bluemap(sc
)[start
];
363 for (i
= start
; i
< ecount
; i
++)
370 * Return the address that would map the given device at the given
371 * offset, allowing for the given protection, or return -1 for error.
374 cgtwommap(dev_t dev
, off_t off
, int prot
)
376 extern int sparc_vme_mmap_cookie(vme_addr_t
, vme_am_t
,
377 bus_space_handle_t
*);
379 register struct cgtwo_softc
*sc
= device_lookup_private(&cgtwo_cd
,
382 bus_space_handle_t bh
;
387 if (off
>= sc
->sc_fb
.fb_type
.fb_size
)
390 /* Apparently, the pixels are in 32-bit data space */
391 mod
= 0x3d; /* VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA */
393 if (sparc_vme_mmap_cookie(sc
->sc_paddr
+ off
, mod
, &bh
) != 0)
396 return ((paddr_t
)bh
);