1*8e9f762cSriastradh /* $NetBSD: bt463.c,v 1.18 2018/01/24 05:35:58 riastradh Exp $ */
2c0a4c9e6Snathanw
3c0a4c9e6Snathanw /*-
4c0a4c9e6Snathanw * Copyright (c) 1998 The NetBSD Foundation, Inc.
5c0a4c9e6Snathanw * All rights reserved.
6c0a4c9e6Snathanw *
7c0a4c9e6Snathanw * This code is derived from software contributed to The NetBSD Foundation
8c0a4c9e6Snathanw * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9c0a4c9e6Snathanw * NASA Ames Research Center.
10c0a4c9e6Snathanw *
11c0a4c9e6Snathanw * Redistribution and use in source and binary forms, with or without
12c0a4c9e6Snathanw * modification, are permitted provided that the following conditions
13c0a4c9e6Snathanw * are met:
14c0a4c9e6Snathanw * 1. Redistributions of source code must retain the above copyright
15c0a4c9e6Snathanw * notice, this list of conditions and the following disclaimer.
16c0a4c9e6Snathanw * 2. Redistributions in binary form must reproduce the above copyright
17c0a4c9e6Snathanw * notice, this list of conditions and the following disclaimer in the
18c0a4c9e6Snathanw * documentation and/or other materials provided with the distribution.
19c0a4c9e6Snathanw *
20c0a4c9e6Snathanw * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21c0a4c9e6Snathanw * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22c0a4c9e6Snathanw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23c0a4c9e6Snathanw * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24c0a4c9e6Snathanw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25c0a4c9e6Snathanw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26c0a4c9e6Snathanw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27c0a4c9e6Snathanw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28c0a4c9e6Snathanw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29c0a4c9e6Snathanw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30c0a4c9e6Snathanw * POSSIBILITY OF SUCH DAMAGE.
31c0a4c9e6Snathanw */
32c0a4c9e6Snathanw
33c0a4c9e6Snathanw /*
34c0a4c9e6Snathanw * Copyright (c) 1995, 1996 Carnegie-Mellon University.
35c0a4c9e6Snathanw * All rights reserved.
36c0a4c9e6Snathanw *
37c0a4c9e6Snathanw * Author: Chris G. Demetriou
38c0a4c9e6Snathanw *
39c0a4c9e6Snathanw * Permission to use, copy, modify and distribute this software and
40c0a4c9e6Snathanw * its documentation is hereby granted, provided that both the copyright
41c0a4c9e6Snathanw * notice and this permission notice appear in all copies of the
42c0a4c9e6Snathanw * software, derivative works or modified versions, and any portions
43c0a4c9e6Snathanw * thereof, and that both notices appear in supporting documentation.
44c0a4c9e6Snathanw *
45c0a4c9e6Snathanw * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46c0a4c9e6Snathanw * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
47c0a4c9e6Snathanw * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48c0a4c9e6Snathanw *
49c0a4c9e6Snathanw * Carnegie Mellon requests users of this software to return to
50c0a4c9e6Snathanw *
51c0a4c9e6Snathanw * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
52c0a4c9e6Snathanw * School of Computer Science
53c0a4c9e6Snathanw * Carnegie Mellon University
54c0a4c9e6Snathanw * Pittsburgh PA 15213-3890
55c0a4c9e6Snathanw *
56c0a4c9e6Snathanw * any improvements or extensions that they make and grant Carnegie the
57c0a4c9e6Snathanw * rights to redistribute these changes.
58c0a4c9e6Snathanw */
59c0a4c9e6Snathanw
60c0a4c9e6Snathanw /* This code was derived from and originally located in sys/dev/pci/
61c0a4c9e6Snathanw * NetBSD: tga_bt463.c,v 1.5 2000/03/04 10:27:59 elric Exp
62c0a4c9e6Snathanw */
63c0a4c9e6Snathanw
64a4bae8b0Slukem #include <sys/cdefs.h>
65*8e9f762cSriastradh __KERNEL_RCSID(0, "$NetBSD: bt463.c,v 1.18 2018/01/24 05:35:58 riastradh Exp $");
66a4bae8b0Slukem
67c0a4c9e6Snathanw #include <sys/param.h>
68c0a4c9e6Snathanw #include <sys/systm.h>
69c0a4c9e6Snathanw #include <sys/device.h>
70c0a4c9e6Snathanw #include <sys/buf.h>
71c0a4c9e6Snathanw #include <sys/kernel.h>
72c0a4c9e6Snathanw #include <sys/malloc.h>
73314f1e97Smrg
74c0a4c9e6Snathanw #include <dev/pci/pcivar.h>
75c0a4c9e6Snathanw #include <dev/pci/tgareg.h>
76c0a4c9e6Snathanw #include <dev/pci/tgavar.h>
77c0a4c9e6Snathanw #include <dev/ic/bt463reg.h>
78c0a4c9e6Snathanw #include <dev/ic/bt463var.h>
79c0a4c9e6Snathanw
80c0a4c9e6Snathanw #include <dev/wscons/wsconsio.h>
81c0a4c9e6Snathanw
82c0a4c9e6Snathanw /*
83c0a4c9e6Snathanw * Functions exported via the RAMDAC configuration table.
84c0a4c9e6Snathanw */
8518db93c7Sperry void bt463_init(struct ramdac_cookie *);
8618db93c7Sperry int bt463_set_cmap(struct ramdac_cookie *, struct wsdisplay_cmap *);
8718db93c7Sperry int bt463_get_cmap(struct ramdac_cookie *, struct wsdisplay_cmap *);
8818db93c7Sperry int bt463_set_cursor(struct ramdac_cookie *, struct wsdisplay_cursor *);
8918db93c7Sperry int bt463_get_cursor(struct ramdac_cookie *, struct wsdisplay_cursor *);
9018db93c7Sperry int bt463_set_curpos(struct ramdac_cookie *, struct wsdisplay_curpos *);
9118db93c7Sperry int bt463_get_curpos(struct ramdac_cookie *, struct wsdisplay_curpos *);
9218db93c7Sperry int bt463_get_curmax(struct ramdac_cookie *, struct wsdisplay_curpos *);
9318db93c7Sperry int bt463_check_curcmap(struct ramdac_cookie *,
9418db93c7Sperry struct wsdisplay_cursor *cursorp);
9518db93c7Sperry void bt463_set_curcmap(struct ramdac_cookie *,
9618db93c7Sperry struct wsdisplay_cursor *cursorp);
9718db93c7Sperry int bt463_get_curcmap(struct ramdac_cookie *,
9818db93c7Sperry struct wsdisplay_cursor *cursorp);
99c0a4c9e6Snathanw
100c0a4c9e6Snathanw #ifdef BT463_DEBUG
10118db93c7Sperry int bt463_store(void *);
10218db93c7Sperry int bt463_debug(void *);
10318db93c7Sperry int bt463_readback(void *);
10418db93c7Sperry void bt463_copyback(void *);
105c0a4c9e6Snathanw #endif
106c0a4c9e6Snathanw
107c0a4c9e6Snathanw struct ramdac_funcs bt463_funcsstruct = {
108c0a4c9e6Snathanw "Bt463",
109c0a4c9e6Snathanw bt463_register,
110c0a4c9e6Snathanw bt463_init,
111c0a4c9e6Snathanw bt463_set_cmap,
112c0a4c9e6Snathanw bt463_get_cmap,
113c0a4c9e6Snathanw bt463_set_cursor,
114c0a4c9e6Snathanw bt463_get_cursor,
115c0a4c9e6Snathanw bt463_set_curpos,
116c0a4c9e6Snathanw bt463_get_curpos,
117c0a4c9e6Snathanw bt463_get_curmax,
118c0a4c9e6Snathanw bt463_check_curcmap,
119c0a4c9e6Snathanw bt463_set_curcmap,
120c0a4c9e6Snathanw bt463_get_curcmap,
12194448f7eSelric NULL,
122c0a4c9e6Snathanw };
123c0a4c9e6Snathanw
124c0a4c9e6Snathanw /*
125c0a4c9e6Snathanw * Private data.
126c0a4c9e6Snathanw */
127c0a4c9e6Snathanw struct bt463data {
128c0a4c9e6Snathanw void *cookie; /* This is what is passed
129c0a4c9e6Snathanw * around, and is probably
130c0a4c9e6Snathanw * struct tga_devconfig *
131c0a4c9e6Snathanw */
132c0a4c9e6Snathanw
13318db93c7Sperry int (*ramdac_sched_update)(void *, void (*)(void *));
13418db93c7Sperry void (*ramdac_wr)(void *, u_int, u_int8_t);
13518db93c7Sperry u_int8_t (*ramdac_rd)(void *, u_int);
136c0a4c9e6Snathanw
137c0a4c9e6Snathanw int changed; /* what changed; see below */
138c0a4c9e6Snathanw char curcmap_r[2]; /* cursor colormap */
139c0a4c9e6Snathanw char curcmap_g[2];
140c0a4c9e6Snathanw char curcmap_b[2];
141e07f0b93Schs char tmpcurcmap_r[2]; /* tmp cursor colormap */
142e07f0b93Schs char tmpcurcmap_g[2];
143e07f0b93Schs char tmpcurcmap_b[2];
144c0a4c9e6Snathanw char cmap_r[BT463_NCMAP_ENTRIES]; /* colormap */
145c0a4c9e6Snathanw char cmap_g[BT463_NCMAP_ENTRIES];
146c0a4c9e6Snathanw char cmap_b[BT463_NCMAP_ENTRIES];
147c0a4c9e6Snathanw int window_type[16]; /* 16 24-bit window type table entries */
148c0a4c9e6Snathanw };
149c0a4c9e6Snathanw
150a5598651Snathanw /* When we're doing console initialization, there's no
151a5598651Snathanw * way to get our cookie back to the video card's softc
152a5598651Snathanw * before we call sched_update. So we stash it here,
153a5598651Snathanw * and bt463_update will look for it here first.
154a5598651Snathanw */
155a5598651Snathanw static struct bt463data *console_data;
156a5598651Snathanw
157a5598651Snathanw
158c0a4c9e6Snathanw #define BTWREG(data, addr, val) do { bt463_wraddr((data), (addr)); \
159c0a4c9e6Snathanw (data)->ramdac_wr((data)->cookie, BT463_REG_IREG_DATA, (val)); } while (0)
160c0a4c9e6Snathanw #define BTWNREG(data, val) (data)->ramdac_wr((data)->cookie, \
161c0a4c9e6Snathanw BT463_REG_IREG_DATA, (val))
162c0a4c9e6Snathanw #define BTRREG(data, addr) (bt463_wraddr((data), (addr)), \
163c0a4c9e6Snathanw (data)->ramdac_rd((data)->cookie, BT463_REG_IREG_DATA))
164c0a4c9e6Snathanw #define BTRNREG(data) ((data)->ramdac_rd((data)->cookie, BT463_REG_IREG_DATA))
165c0a4c9e6Snathanw
166c0a4c9e6Snathanw #define DATA_CURCMAP_CHANGED 0x01 /* cursor colormap changed */
167c0a4c9e6Snathanw #define DATA_CMAP_CHANGED 0x02 /* colormap changed */
168c0a4c9e6Snathanw #define DATA_WTYPE_CHANGED 0x04 /* window type table changed */
169c0a4c9e6Snathanw #define DATA_ALL_CHANGED 0x07
170c0a4c9e6Snathanw
171c0a4c9e6Snathanw /*
172c0a4c9e6Snathanw * Internal functions.
173c0a4c9e6Snathanw */
174c0a4c9e6Snathanw
17518db93c7Sperry void bt463_update(void *);
176c0a4c9e6Snathanw
177106e9eabSriastradh static inline void
bt463_wraddr(struct bt463data * data,u_int16_t ireg)178106e9eabSriastradh bt463_wraddr(struct bt463data *data, u_int16_t ireg)
179106e9eabSriastradh {
180106e9eabSriastradh data->ramdac_wr(data->cookie, BT463_REG_ADDR_LOW, ireg & 0xff);
181106e9eabSriastradh data->ramdac_wr(data->cookie, BT463_REG_ADDR_HIGH, (ireg >> 8) & 0xff);
182106e9eabSriastradh }
183c0a4c9e6Snathanw
184c0a4c9e6Snathanw /*****************************************************************************/
185c0a4c9e6Snathanw
186c0a4c9e6Snathanw /*
187c0a4c9e6Snathanw * Functions exported via the RAMDAC configuration table.
188c0a4c9e6Snathanw */
189c0a4c9e6Snathanw
190c0a4c9e6Snathanw struct ramdac_funcs *
bt463_funcs(void)191c0a4c9e6Snathanw bt463_funcs(void)
192c0a4c9e6Snathanw {
193c0a4c9e6Snathanw return &bt463_funcsstruct;
194c0a4c9e6Snathanw }
195c0a4c9e6Snathanw
196c0a4c9e6Snathanw struct ramdac_cookie *
bt463_register(void * v,int (* sched_update)(void *,void (*)(void *)),void (* wr)(void *,u_int,u_int8_t),u_int8_t (* rd)(void *,u_int))1971d7f24eaSmatt bt463_register(
1981d7f24eaSmatt void *v,
1991d7f24eaSmatt int (*sched_update)(void *, void (*)(void *)),
2001d7f24eaSmatt void (*wr)(void *, u_int, u_int8_t),
2011d7f24eaSmatt u_int8_t (*rd)(void *, u_int))
202c0a4c9e6Snathanw {
203c0a4c9e6Snathanw struct bt463data *data;
204c0a4c9e6Snathanw /*
205c0a4c9e6Snathanw * XXX -- comment out of date. rcd.
206c0a4c9e6Snathanw * If we should allocate a new private info struct, do so.
207c0a4c9e6Snathanw * Otherwise, use the one we have (if it's there), or
208c0a4c9e6Snathanw * use the temporary one on the stack.
209c0a4c9e6Snathanw */
210c0a4c9e6Snathanw data = malloc(sizeof *data, M_DEVBUF, M_WAITOK);
211c0a4c9e6Snathanw /* XXX -- if !data */
212c0a4c9e6Snathanw data->cookie = v;
213c0a4c9e6Snathanw data->ramdac_sched_update = sched_update;
214c0a4c9e6Snathanw data->ramdac_wr = wr;
215c0a4c9e6Snathanw data->ramdac_rd = rd;
216c0a4c9e6Snathanw return (struct ramdac_cookie *)data;
217c0a4c9e6Snathanw }
218c0a4c9e6Snathanw
219c0a4c9e6Snathanw /*
220c0a4c9e6Snathanw * This function exists solely to provide a means to init
221c0a4c9e6Snathanw * the RAMDAC without first registering. It is useful for
222c0a4c9e6Snathanw * initializing the console early on.
223c0a4c9e6Snathanw */
224c0a4c9e6Snathanw void
bt463_cninit(void * v,int (* sched_update)(void *,void (*)(void *)),void (* wr)(void *,u_int,u_int8_t),u_int8_t (* rd)(void *,u_int))2251d7f24eaSmatt bt463_cninit(
2261d7f24eaSmatt void *v,
2271d7f24eaSmatt int (*sched_update)(void *, void (*)(void *)),
2281d7f24eaSmatt void (*wr)(void *, u_int, u_int8_t),
2291d7f24eaSmatt u_int8_t (*rd)(void *, u_int))
230c0a4c9e6Snathanw {
231c0a4c9e6Snathanw struct bt463data tmp, *data = &tmp;
232c0a4c9e6Snathanw data->cookie = v;
233c0a4c9e6Snathanw data->ramdac_sched_update = sched_update;
234c0a4c9e6Snathanw data->ramdac_wr = wr;
235c0a4c9e6Snathanw data->ramdac_rd = rd;
236a5598651Snathanw /* Set up console_data so that when bt463_update is called back,
237a5598651Snathanw * it can use the right information.
238a5598651Snathanw */
239a5598651Snathanw console_data = data;
240c0a4c9e6Snathanw bt463_init((struct ramdac_cookie *)data);
241a5598651Snathanw console_data = NULL;
242c0a4c9e6Snathanw }
243c0a4c9e6Snathanw
244c0a4c9e6Snathanw void
bt463_init(struct ramdac_cookie * rc)245454af1c0Sdsl bt463_init(struct ramdac_cookie *rc)
246c0a4c9e6Snathanw {
247c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
248c0a4c9e6Snathanw
249c0a4c9e6Snathanw int i;
250c0a4c9e6Snathanw
251c0a4c9e6Snathanw /*
252c0a4c9e6Snathanw * Init the BT463 for normal operation.
253c0a4c9e6Snathanw */
254c0a4c9e6Snathanw
255c0a4c9e6Snathanw
256c0a4c9e6Snathanw /*
257c0a4c9e6Snathanw * Setup:
258c0a4c9e6Snathanw * reg 0: 4:1 multiplexing, 25/75 blink.
259c0a4c9e6Snathanw * reg 1: Overlay mapping: mapped to common palette,
260c0a4c9e6Snathanw * 14 window type entries, 24-plane configuration mode,
261c0a4c9e6Snathanw * 4 overlay planes, underlays disabled, no cursor.
262c0a4c9e6Snathanw * reg 2: sync-on-green enabled, pedestal enabled.
263c0a4c9e6Snathanw */
264c0a4c9e6Snathanw
265c0a4c9e6Snathanw BTWREG(data, BT463_IREG_COMMAND_0, 0x40);
266c0a4c9e6Snathanw BTWREG(data, BT463_IREG_COMMAND_1, 0x48);
26794448f7eSelric BTWREG(data, BT463_IREG_COMMAND_2, 0x40);
268c0a4c9e6Snathanw
269c0a4c9e6Snathanw /*
270c0a4c9e6Snathanw * Initialize the read mask.
271c0a4c9e6Snathanw */
272c0a4c9e6Snathanw bt463_wraddr(data, BT463_IREG_READ_MASK_P0_P7);
273c0a4c9e6Snathanw for (i = 0; i < 4; i++)
274c0a4c9e6Snathanw BTWNREG(data, 0xff);
275c0a4c9e6Snathanw
276c0a4c9e6Snathanw /*
277c0a4c9e6Snathanw * Initialize the blink mask.
278c0a4c9e6Snathanw */
279c0a4c9e6Snathanw bt463_wraddr(data, BT463_IREG_BLINK_MASK_P0_P7);
280c0a4c9e6Snathanw for (i = 0; i < 4; i++)
281c0a4c9e6Snathanw BTWNREG(data, 0);
282c0a4c9e6Snathanw
283c0a4c9e6Snathanw
284c0a4c9e6Snathanw /*
285c0a4c9e6Snathanw * Clear test register
286c0a4c9e6Snathanw */
287c0a4c9e6Snathanw BTWREG(data, BT463_IREG_TEST, 0);
288c0a4c9e6Snathanw
289c0a4c9e6Snathanw /*
2909fa0b176Swiz * Initialize the RAMDAC info struct to hold all of our
291c0a4c9e6Snathanw * data, and fill it in.
292c0a4c9e6Snathanw */
293c0a4c9e6Snathanw data->changed = DATA_ALL_CHANGED;
294c0a4c9e6Snathanw
295c0a4c9e6Snathanw /* initial cursor colormap: 0 is black, 1 is white */
296c0a4c9e6Snathanw data->curcmap_r[0] = data->curcmap_g[0] = data->curcmap_b[0] = 0;
297c0a4c9e6Snathanw data->curcmap_r[1] = data->curcmap_g[1] = data->curcmap_b[1] = 0xff;
298c0a4c9e6Snathanw
299c0a4c9e6Snathanw /* Initial colormap: 0 is black, everything else is white */
300c0a4c9e6Snathanw data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0;
301c0a4c9e6Snathanw for (i = 1; i < 256; i++)
302c0a4c9e6Snathanw data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 255;
303c0a4c9e6Snathanw
304c0a4c9e6Snathanw
305c0a4c9e6Snathanw /* Initialize the window type table:
306c0a4c9e6Snathanw *
307c0a4c9e6Snathanw * Entry 0: 24-plane truecolor, overlays enabled, bypassed.
308c0a4c9e6Snathanw *
309c0a4c9e6Snathanw * Lookup table bypass: yes ( 1 << 23 & 0x800000) 800000
310c0a4c9e6Snathanw * Colormap address: 0x000 (0x000 << 17 & 0x7e0000) 0
311c0a4c9e6Snathanw * Overlay mask: 0xf ( 0xf << 13 & 0x01e000) 1e000
312c0a4c9e6Snathanw * Overlay location: P<27:24> ( 0 << 12 & 0x001000) 0
313c0a4c9e6Snathanw * Display mode: Truecolor ( 0 << 9 & 0x000e00) 000
314c0a4c9e6Snathanw * Number of planes: 8 ( 8 << 5 & 0x0001e0) 100
315c0a4c9e6Snathanw * Plane shift: 0 ( 0 << 0 & 0x00001f) 0
316c0a4c9e6Snathanw * --------
317c0a4c9e6Snathanw * 0x81e100
318c0a4c9e6Snathanw */
319c0a4c9e6Snathanw data->window_type[0] = 0x81e100;
320c0a4c9e6Snathanw
321c0a4c9e6Snathanw /* Entry 1: 8-plane pseudocolor in the bottom 8 bits,
322c0a4c9e6Snathanw * overlays enabled, colormap starting at 0.
323c0a4c9e6Snathanw *
324c0a4c9e6Snathanw * Lookup table bypass: no ( 0 << 23 & 0x800000) 0
325c0a4c9e6Snathanw * Colormap address: 0x000 (0x000 << 17 & 0x7e0000) 0
326c0a4c9e6Snathanw * Overlay mask: 0xf ( 0xf << 13 & 0x01e000) 0x1e000
327c0a4c9e6Snathanw * Overlay location: P<27:24> ( 0 << 12 & 0x001000) 0
328c0a4c9e6Snathanw * Display mode: Pseudocolor ( 1 << 9 & 0x000e00) 0x200
329c0a4c9e6Snathanw * Number of planes: 8 ( 8 << 5 & 0x0001e0) 0x100
330c0a4c9e6Snathanw * Plane shift: 16 ( 0x10 << 0 & 0x00001f) 10
331c0a4c9e6Snathanw * --------
332c0a4c9e6Snathanw * 0x01e310
333c0a4c9e6Snathanw */
334c0a4c9e6Snathanw data->window_type[1] = 0x01e310;
335c0a4c9e6Snathanw
336c0a4c9e6Snathanw /* The colormap interface to the world only supports one colormap,
337c0a4c9e6Snathanw * so having an entry for the 'alternate' colormap in the bt463
338c0a4c9e6Snathanw * probably isn't useful.
339c0a4c9e6Snathanw */
340c0a4c9e6Snathanw
341c0a4c9e6Snathanw /* Fill the remaining table entries with clones of entry 0 until we
342c0a4c9e6Snathanw * figure out a better use for them.
343c0a4c9e6Snathanw */
344c0a4c9e6Snathanw
345c0a4c9e6Snathanw for (i = 2; i < BT463_NWTYPE_ENTRIES; i++) {
346c0a4c9e6Snathanw data->window_type[i] = 0x81e100;
347c0a4c9e6Snathanw }
348c0a4c9e6Snathanw
349c0a4c9e6Snathanw data->ramdac_sched_update(data->cookie, bt463_update);
350c0a4c9e6Snathanw
351c0a4c9e6Snathanw }
352c0a4c9e6Snathanw
353c0a4c9e6Snathanw int
bt463_set_cmap(struct ramdac_cookie * rc,struct wsdisplay_cmap * cmapp)354454af1c0Sdsl bt463_set_cmap(struct ramdac_cookie *rc, struct wsdisplay_cmap *cmapp)
355c0a4c9e6Snathanw {
356c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
357ceb38aa7Sjdolecek u_int count, index;
358e07f0b93Schs uint8_t r[BT463_NCMAP_ENTRIES];
359e07f0b93Schs uint8_t g[BT463_NCMAP_ENTRIES];
360e07f0b93Schs uint8_t b[BT463_NCMAP_ENTRIES];
361e07f0b93Schs int s, error;
362c0a4c9e6Snathanw
363ceb38aa7Sjdolecek if (cmapp->index >= BT463_NCMAP_ENTRIES ||
3648dd04cdcSitojun cmapp->count > BT463_NCMAP_ENTRIES - cmapp->index)
365c0a4c9e6Snathanw return (EINVAL);
366c0a4c9e6Snathanw
367c0a4c9e6Snathanw index = cmapp->index;
368c0a4c9e6Snathanw count = cmapp->count;
369e07f0b93Schs error = copyin(cmapp->red, &r[index], count);
370e07f0b93Schs if (error)
371e07f0b93Schs return error;
372e07f0b93Schs error = copyin(cmapp->green, &g[index], count);
373e07f0b93Schs if (error)
374e07f0b93Schs return error;
375e07f0b93Schs error = copyin(cmapp->blue, &b[index], count);
376e07f0b93Schs if (error)
377e07f0b93Schs return error;
378e07f0b93Schs s = spltty();
379e07f0b93Schs memcpy(&data->cmap_r[index], &r[index], count);
380e07f0b93Schs memcpy(&data->cmap_g[index], &g[index], count);
381e07f0b93Schs memcpy(&data->cmap_b[index], &b[index], count);
382c0a4c9e6Snathanw data->changed |= DATA_CMAP_CHANGED;
383c0a4c9e6Snathanw data->ramdac_sched_update(data->cookie, bt463_update);
384c0a4c9e6Snathanw splx(s);
385c0a4c9e6Snathanw return (0);
386c0a4c9e6Snathanw }
387c0a4c9e6Snathanw
388c0a4c9e6Snathanw int
bt463_get_cmap(struct ramdac_cookie * rc,struct wsdisplay_cmap * cmapp)389454af1c0Sdsl bt463_get_cmap(struct ramdac_cookie *rc, struct wsdisplay_cmap *cmapp)
390c0a4c9e6Snathanw {
391c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
3928dd04cdcSitojun u_int count, index;
3938dd04cdcSitojun int error;
394c0a4c9e6Snathanw
3958dd04cdcSitojun if (cmapp->index >= BT463_NCMAP_ENTRIES ||
3968dd04cdcSitojun cmapp->count > BT463_NCMAP_ENTRIES - cmapp->index)
397c0a4c9e6Snathanw return (EINVAL);
398c0a4c9e6Snathanw
399c0a4c9e6Snathanw count = cmapp->count;
400c0a4c9e6Snathanw index = cmapp->index;
401c0a4c9e6Snathanw
402c0a4c9e6Snathanw error = copyout(&data->cmap_r[index], cmapp->red, count);
403c0a4c9e6Snathanw if (error)
404c0a4c9e6Snathanw return (error);
405c0a4c9e6Snathanw error = copyout(&data->cmap_g[index], cmapp->green, count);
406c0a4c9e6Snathanw if (error)
407c0a4c9e6Snathanw return (error);
408c0a4c9e6Snathanw error = copyout(&data->cmap_b[index], cmapp->blue, count);
409c0a4c9e6Snathanw return (error);
410c0a4c9e6Snathanw }
411c0a4c9e6Snathanw
412c0a4c9e6Snathanw int
bt463_check_curcmap(struct ramdac_cookie * rc,struct wsdisplay_cursor * cursorp)413454af1c0Sdsl bt463_check_curcmap(struct ramdac_cookie *rc, struct wsdisplay_cursor *cursorp)
414c0a4c9e6Snathanw {
415e07f0b93Schs struct bt463data *data = (struct bt463data *)rc;
416e07f0b93Schs int count, index, error;
417c0a4c9e6Snathanw
418e07f0b93Schs if (cursorp->cmap.index > 2 ||
419*8e9f762cSriastradh cursorp->cmap.count > 2 - cursorp->cmap.index)
420c0a4c9e6Snathanw return (EINVAL);
421c0a4c9e6Snathanw count = cursorp->cmap.count;
422e07f0b93Schs index = cursorp->cmap.index;
423e07f0b93Schs error = copyin(cursorp->cmap.red, &data->tmpcurcmap_r[index], count);
424e07f0b93Schs if (error)
425e07f0b93Schs return error;
426e07f0b93Schs error = copyin(cursorp->cmap.green, &data->tmpcurcmap_g[index], count);
427e07f0b93Schs if (error)
428e07f0b93Schs return error;
429e07f0b93Schs error = copyin(cursorp->cmap.blue, &data->tmpcurcmap_b[index], count);
430e07f0b93Schs if (error)
431e07f0b93Schs return error;
432c0a4c9e6Snathanw return (0);
433c0a4c9e6Snathanw }
434c0a4c9e6Snathanw
435c0a4c9e6Snathanw void
bt463_set_curcmap(struct ramdac_cookie * rc,struct wsdisplay_cursor * cursorp)436454af1c0Sdsl bt463_set_curcmap(struct ramdac_cookie *rc, struct wsdisplay_cursor *cursorp)
437c0a4c9e6Snathanw {
438c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
439c0a4c9e6Snathanw int count, index;
440c0a4c9e6Snathanw
441c0a4c9e6Snathanw count = cursorp->cmap.count;
442c0a4c9e6Snathanw index = cursorp->cmap.index;
443e07f0b93Schs memcpy(&data->curcmap_r[index], &data->tmpcurcmap_r[index], count);
444e07f0b93Schs memcpy(&data->curcmap_g[index], &data->tmpcurcmap_g[index], count);
445e07f0b93Schs memcpy(&data->curcmap_b[index], &data->tmpcurcmap_b[index], count);
446c0a4c9e6Snathanw data->changed |= DATA_CURCMAP_CHANGED;
447c0a4c9e6Snathanw data->ramdac_sched_update(data->cookie, bt463_update);
448c0a4c9e6Snathanw }
449c0a4c9e6Snathanw
450c0a4c9e6Snathanw int
bt463_get_curcmap(struct ramdac_cookie * rc,struct wsdisplay_cursor * cursorp)451454af1c0Sdsl bt463_get_curcmap(struct ramdac_cookie *rc, struct wsdisplay_cursor *cursorp)
452c0a4c9e6Snathanw {
453c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
454c0a4c9e6Snathanw int error;
455c0a4c9e6Snathanw
456c0a4c9e6Snathanw cursorp->cmap.index = 0; /* DOCMAP */
457c0a4c9e6Snathanw cursorp->cmap.count = 2;
458c0a4c9e6Snathanw if (cursorp->cmap.red != NULL) {
459c0a4c9e6Snathanw error = copyout(data->curcmap_r, cursorp->cmap.red, 2);
460c0a4c9e6Snathanw if (error)
461c0a4c9e6Snathanw return (error);
462c0a4c9e6Snathanw }
463c0a4c9e6Snathanw if (cursorp->cmap.green != NULL) {
464c0a4c9e6Snathanw error = copyout(data->curcmap_g, cursorp->cmap.green, 2);
465c0a4c9e6Snathanw if (error)
466c0a4c9e6Snathanw return (error);
467c0a4c9e6Snathanw }
468c0a4c9e6Snathanw if (cursorp->cmap.blue != NULL) {
469c0a4c9e6Snathanw error = copyout(data->curcmap_b, cursorp->cmap.blue, 2);
470c0a4c9e6Snathanw if (error)
471c0a4c9e6Snathanw return (error);
472c0a4c9e6Snathanw }
473c0a4c9e6Snathanw return (0);
474c0a4c9e6Snathanw }
475c0a4c9e6Snathanw
476c0a4c9e6Snathanw
477c0a4c9e6Snathanw /*****************************************************************************/
478c0a4c9e6Snathanw
479c0a4c9e6Snathanw /*
480c0a4c9e6Snathanw * Internal functions.
481c0a4c9e6Snathanw */
482c0a4c9e6Snathanw
483c0a4c9e6Snathanw #ifdef BT463_DEBUG
bt463_store(void * v)484c0a4c9e6Snathanw int bt463_store(void *v)
485c0a4c9e6Snathanw {
486c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)v;
487c0a4c9e6Snathanw
488c0a4c9e6Snathanw data->changed = DATA_ALL_CHANGED;
489c0a4c9e6Snathanw data->ramdac_sched_update(data->cookie, bt463_update);
490c0a4c9e6Snathanw printf("Scheduled bt463 store\n");
491c0a4c9e6Snathanw
492c0a4c9e6Snathanw return 0;
493c0a4c9e6Snathanw }
494c0a4c9e6Snathanw
495c0a4c9e6Snathanw
bt463_readback(void * v)496c0a4c9e6Snathanw int bt463_readback(void *v)
497c0a4c9e6Snathanw {
498c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)v;
499c0a4c9e6Snathanw
500c0a4c9e6Snathanw data->ramdac_sched_update(data->cookie, bt463_copyback);
501c0a4c9e6Snathanw printf("Scheduled bt463 copyback\n");
502c0a4c9e6Snathanw return 0;
503c0a4c9e6Snathanw }
504c0a4c9e6Snathanw
505c0a4c9e6Snathanw int
bt463_debug(void * v)506454af1c0Sdsl bt463_debug(void *v)
507c0a4c9e6Snathanw {
508c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)v;
509c0a4c9e6Snathanw int i;
510c0a4c9e6Snathanw u_int8_t val;
511c0a4c9e6Snathanw
512c0a4c9e6Snathanw printf("BT463 main regs:\n");
513c0a4c9e6Snathanw for (i = 0x200; i < 0x20F; i ++) {
514c0a4c9e6Snathanw val = BTRREG(data, i);
515c0a4c9e6Snathanw printf(" $%04x %02x\n", i, val);
516c0a4c9e6Snathanw }
517c0a4c9e6Snathanw
518c0a4c9e6Snathanw printf("BT463 revision register:\n");
519c0a4c9e6Snathanw val = BTRREG(data, 0x220);
520c0a4c9e6Snathanw printf(" $%04x %02x\n", 0x220, val);
521c0a4c9e6Snathanw
522c0a4c9e6Snathanw printf("BT463 window type table (from softc):\n");
523c0a4c9e6Snathanw
524c0a4c9e6Snathanw for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
525c0a4c9e6Snathanw printf("%02x %06x\n", i, data->window_type[i]);
526c0a4c9e6Snathanw }
527c0a4c9e6Snathanw
528c0a4c9e6Snathanw return 0;
529c0a4c9e6Snathanw }
530c0a4c9e6Snathanw
531c0a4c9e6Snathanw void
bt463_copyback(void * p)532454af1c0Sdsl bt463_copyback(void *p)
533c0a4c9e6Snathanw {
534c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)p;
535c0a4c9e6Snathanw int i;
536c0a4c9e6Snathanw
537c0a4c9e6Snathanw for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
538c0a4c9e6Snathanw bt463_wraddr(data, BT463_IREG_WINDOW_TYPE_TABLE + i);
539c0a4c9e6Snathanw data->window_type[i] = (BTRNREG(data) & 0xff); /* B0-7 */
540c0a4c9e6Snathanw data->window_type[i] |= (BTRNREG(data) & 0xff) << 8; /* B8-15 */
541c0a4c9e6Snathanw data->window_type[i] |= (BTRNREG(data) & 0xff) << 16; /* B16-23 */
542c0a4c9e6Snathanw }
543c0a4c9e6Snathanw }
544c0a4c9e6Snathanw #endif
545c0a4c9e6Snathanw
546c0a4c9e6Snathanw void
bt463_update(void * p)547454af1c0Sdsl bt463_update(void *p)
548c0a4c9e6Snathanw {
549c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)p;
550c0a4c9e6Snathanw int i, v;
551c0a4c9e6Snathanw
552a5598651Snathanw if (console_data != NULL) {
553a5598651Snathanw /* The cookie passed in from sched_update is incorrect. Use the
554a5598651Snathanw * right one.
555a5598651Snathanw */
556a5598651Snathanw data = console_data;
557a5598651Snathanw }
558a5598651Snathanw
559c0a4c9e6Snathanw v = data->changed;
560c0a4c9e6Snathanw
561c0a4c9e6Snathanw /* The Bt463 won't accept window type data except during a blanking
562c0a4c9e6Snathanw * interval, so we do this early in the interrupt.
563c0a4c9e6Snathanw * Blanking the screen might also be a good idea, but it can cause
564c0a4c9e6Snathanw * unpleasant flashing and is hard to do from this side of the
565c0a4c9e6Snathanw * ramdac interface.
566c0a4c9e6Snathanw */
567c0a4c9e6Snathanw if (v & DATA_WTYPE_CHANGED) {
568c0a4c9e6Snathanw /* spit out the window type data */
569c0a4c9e6Snathanw for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
570c0a4c9e6Snathanw bt463_wraddr(data, BT463_IREG_WINDOW_TYPE_TABLE + i);
571c0a4c9e6Snathanw BTWNREG(data, (data->window_type[i]) & 0xff); /* B0-7 */
572c0a4c9e6Snathanw BTWNREG(data, (data->window_type[i] >> 8) & 0xff); /* B8-15 */
573c0a4c9e6Snathanw BTWNREG(data, (data->window_type[i] >> 16) & 0xff); /* B16-23 */
574c0a4c9e6Snathanw }
575c0a4c9e6Snathanw }
576c0a4c9e6Snathanw
577c0a4c9e6Snathanw if (v & DATA_CURCMAP_CHANGED) {
578c0a4c9e6Snathanw bt463_wraddr(data, BT463_IREG_CURSOR_COLOR_0);
579c0a4c9e6Snathanw /* spit out the cursor data */
580c0a4c9e6Snathanw for (i = 0; i < 2; i++) {
581c0a4c9e6Snathanw BTWNREG(data, data->curcmap_r[i]);
582c0a4c9e6Snathanw BTWNREG(data, data->curcmap_g[i]);
583c0a4c9e6Snathanw BTWNREG(data, data->curcmap_b[i]);
584c0a4c9e6Snathanw }
585c0a4c9e6Snathanw }
586c0a4c9e6Snathanw
587c0a4c9e6Snathanw if (v & DATA_CMAP_CHANGED) {
588c0a4c9e6Snathanw bt463_wraddr(data, BT463_IREG_CPALETTE_RAM);
589c0a4c9e6Snathanw /* spit out the colormap data */
590c0a4c9e6Snathanw for (i = 0; i < BT463_NCMAP_ENTRIES; i++) {
591c0a4c9e6Snathanw data->ramdac_wr(data->cookie, BT463_REG_CMAP_DATA,
592c0a4c9e6Snathanw data->cmap_r[i]);
593c0a4c9e6Snathanw data->ramdac_wr(data->cookie, BT463_REG_CMAP_DATA,
594c0a4c9e6Snathanw data->cmap_g[i]);
595c0a4c9e6Snathanw data->ramdac_wr(data->cookie, BT463_REG_CMAP_DATA,
596c0a4c9e6Snathanw data->cmap_b[i]);
597c0a4c9e6Snathanw }
598c0a4c9e6Snathanw }
599c0a4c9e6Snathanw
600c0a4c9e6Snathanw data->changed = 0;
601c0a4c9e6Snathanw }
602c0a4c9e6Snathanw
6031d7f24eaSmatt int
bt463_set_cursor(struct ramdac_cookie * rc,struct wsdisplay_cursor * cur)6041d7f24eaSmatt bt463_set_cursor(
6051d7f24eaSmatt struct ramdac_cookie *rc,
6061d7f24eaSmatt struct wsdisplay_cursor *cur)
607c0a4c9e6Snathanw {
608c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
609c0a4c9e6Snathanw return tga_builtin_set_cursor(data->cookie, cur);
610c0a4c9e6Snathanw }
611c0a4c9e6Snathanw
6121d7f24eaSmatt int
bt463_get_cursor(struct ramdac_cookie * rc,struct wsdisplay_cursor * cur)6131d7f24eaSmatt bt463_get_cursor(
6141d7f24eaSmatt struct ramdac_cookie *rc,
6151d7f24eaSmatt struct wsdisplay_cursor *cur)
616c0a4c9e6Snathanw {
617c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
618c0a4c9e6Snathanw return tga_builtin_get_cursor(data->cookie, cur);
619c0a4c9e6Snathanw }
620c0a4c9e6Snathanw
6211d7f24eaSmatt int
bt463_set_curpos(struct ramdac_cookie * rc,struct wsdisplay_curpos * cur)6221d7f24eaSmatt bt463_set_curpos(
6231d7f24eaSmatt struct ramdac_cookie *rc,
6241d7f24eaSmatt struct wsdisplay_curpos *cur)
625c0a4c9e6Snathanw {
626c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
627c0a4c9e6Snathanw return tga_builtin_set_curpos(data->cookie, cur);
628c0a4c9e6Snathanw }
629c0a4c9e6Snathanw
6301d7f24eaSmatt int
bt463_get_curpos(struct ramdac_cookie * rc,struct wsdisplay_curpos * cur)6311d7f24eaSmatt bt463_get_curpos(
6321d7f24eaSmatt struct ramdac_cookie *rc,
6331d7f24eaSmatt struct wsdisplay_curpos *cur)
634c0a4c9e6Snathanw {
635c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
636c0a4c9e6Snathanw return tga_builtin_get_curpos(data->cookie, cur);
637c0a4c9e6Snathanw }
638c0a4c9e6Snathanw
6391d7f24eaSmatt int
bt463_get_curmax(struct ramdac_cookie * rc,struct wsdisplay_curpos * cur)6401d7f24eaSmatt bt463_get_curmax(
6411d7f24eaSmatt struct ramdac_cookie *rc,
6421d7f24eaSmatt struct wsdisplay_curpos *cur)
643c0a4c9e6Snathanw {
644c0a4c9e6Snathanw struct bt463data *data = (struct bt463data *)rc;
645c0a4c9e6Snathanw return tga_builtin_get_curmax(data->cookie, cur);
646c0a4c9e6Snathanw }
647