1/*	$NetBSD$ */
2
3/*
4 * Copyright (c) 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
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.
10 *
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.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
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.
27 *
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
38 * SUCH DAMAGE.
39 *
40 *	@(#)bt_subr.c	8.2 (Berkeley) 1/21/94
41 */
42
43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD$");
45
46#include <sys/param.h>
47#include <sys/systm.h>
48#include <sys/buf.h>
49#include <sys/errno.h>
50#include <sys/malloc.h>
51
52#include <dev/sun/fbio.h>
53
54#include <dev/sun/btreg.h>
55#include <dev/sun/btvar.h>
56
57/*
58 * Common code for dealing with Brooktree video DACs.
59 * (Contains some software-only code as well, since the colormap
60 * ioctls are shared between the cgthree and cgsix drivers.)
61 */
62
63/*
64 * Implement an FBIOGETCMAP-like ioctl.
65 */
66int
67bt_getcmap(struct fbcmap *p, union bt_cmap *cm, int cmsize, int uspace)
68{
69	u_int i, start, count;
70	int error = 0;
71	u_char *cp, *r, *g, *b;
72	u_char *cbuf = NULL;
73
74	start = p->index;
75	count = p->count;
76	if (start >= cmsize || count > cmsize - start)
77		return (EINVAL);
78
79	if (uspace) {
80		/* Allocate temporary buffer for color values */
81		cbuf = malloc(3 * count * sizeof(char), M_TEMP, M_WAITOK);
82		r = cbuf;
83		g = r + count;
84		b = g + count;
85	} else {
86		/* Direct access in kernel space */
87		r = p->red;
88		g = p->green;
89		b = p->blue;
90	}
91
92	/* Copy colors from BT map to fbcmap */
93	for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 3, i++) {
94		r[i] = cp[0];
95		g[i] = cp[1];
96		b[i] = cp[2];
97	}
98
99	if (uspace) {
100		error = copyout(r, p->red, count);
101		if (error)
102			goto out;
103		error = copyout(g, p->green, count);
104		if (error)
105			goto out;
106		error = copyout(b, p->blue, count);
107		if (error)
108			goto out;
109	}
110
111out:
112	if (cbuf != NULL)
113		free(cbuf, M_TEMP);
114
115	return (error);
116}
117
118/*
119 * Implement the software portion of an FBIOPUTCMAP-like ioctl.
120 */
121int
122bt_putcmap(struct fbcmap *p, union bt_cmap *cm, int cmsize, int uspace)
123{
124	u_int i, start, count;
125	int error = 0;
126	u_char *cp, *r, *g, *b;
127	u_char *cbuf = NULL;
128
129	start = p->index;
130	count = p->count;
131	if (start >= cmsize || count > cmsize - start)
132		return (EINVAL);
133
134	if (uspace) {
135		/* Allocate temporary buffer for color values */
136		cbuf = malloc(3 * count * sizeof(char), M_TEMP, M_WAITOK);
137		r = cbuf;
138		g = r + count;
139		b = g + count;
140		error = copyin(p->red, r, count);
141		if (error)
142			goto out;
143		error = copyin(p->green, g, count);
144		if (error)
145			goto out;
146		error = copyin(p->blue, b, count);
147		if (error)
148			goto out;
149	} else {
150		/* Direct access in kernel space */
151		r = p->red;
152		g = p->green;
153		b = p->blue;
154	}
155
156	/* Copy colors from fbcmap to BT map */
157	for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 3, i++) {
158		cp[0] = r[i];
159		cp[1] = g[i];
160		cp[2] = b[i];
161	}
162
163out:
164	if (cbuf != NULL)
165		free(cbuf, M_TEMP);
166
167	return (error);
168}
169
170/*
171 * Initialize the color map to the default state:
172 *
173 *	- 0 is white			(PROM uses entry 0 for background)
174 *	- all other entries are black	(PROM uses entry 255 for foreground)
175 */
176void
177bt_initcmap(union bt_cmap *cm, int cmsize)
178{
179	int i;
180	u_char *cp;
181
182	cp = &cm->cm_map[0][0];
183	cp[0] = cp[1] = cp[2] = 0xff;
184
185	for (i = 1, cp = &cm->cm_map[i][0]; i < cmsize; cp += 3, i++)
186		cp[0] = cp[1] = cp[2] = 0;
187
188#ifdef RASTERCONSOLE
189	if (cmsize > 16) {
190		/*
191		 * Setup an ANSI map at offset 1, for rasops;
192		 * see dev/fb.c for usage (XXX - this should
193		 * be replaced by more general colormap handling)
194		 */
195		extern u_char rasops_cmap[];
196		memcpy(&cm->cm_map[1][0], rasops_cmap, 3*16);
197	}
198#endif
199}
200
201#if notyet
202static void
203bt_loadcmap_packed256(struct fbdevice *fb, volatile struct bt_regs *bt, int start, int ncolors)
204{
205	u_int v;
206	int count, i;
207	u_char *c[3], **p;
208	struct cmap *cm = &fb->fb_cmap;
209
210	count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
211	bt = &sc->sc_fbc->fbc_dac;
212	bt->bt_addr = BT_D4M4(start);
213
214	/*
215	 * Figure out where to start in the RGB arrays
216	 * See btreg.h for the way RGB triplets are packed into 4-byte words.
217	 */
218	c[0] = &cm->red[(4 * count) / 3];
219	c[1] = &cm->green[(4 * count) / 3];
220	c[2] = &cm->blue[(4 * count) / 3];
221	p = &c[0];
222	i = (4 * count) % 3;	/* This much of the last triplet is already in
223				   the last packed word */
224	while (i--) {
225		c[1-i]++;
226		p++;
227	}
228
229
230	while (--count >= 0) {
231		u_int v = 0;
232
233		/*
234		 * Retrieve four colormap entries, pack them into
235		 * a 32-bit word and write to the hardware register.
236		 */
237		for (i = 0; i < 4; i++) {
238			u_char *cp = *p;
239			v |= *cp++ << (8 * i);
240			*p = cp;
241			if (p++ == &c[2])
242				/* Wrap around */
243				p = &c[0];
244		}
245
246		bt->bt_cmap = v;
247	}
248}
249#endif
250