gsfb.c revision 1.15 1 1.15 christos /* $NetBSD: gsfb.c,v 1.15 2006/02/04 14:54:56 christos Exp $ */
2 1.1 uch
3 1.1 uch /*-
4 1.1 uch * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.1 uch * All rights reserved.
6 1.1 uch *
7 1.1 uch * This code is derived from software contributed to The NetBSD Foundation
8 1.1 uch * by UCHIYAMA Yasushi.
9 1.1 uch *
10 1.1 uch * Redistribution and use in source and binary forms, with or without
11 1.1 uch * modification, are permitted provided that the following conditions
12 1.1 uch * are met:
13 1.1 uch * 1. Redistributions of source code must retain the above copyright
14 1.1 uch * notice, this list of conditions and the following disclaimer.
15 1.1 uch * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 uch * notice, this list of conditions and the following disclaimer in the
17 1.1 uch * documentation and/or other materials provided with the distribution.
18 1.1 uch * 3. All advertising materials mentioning features or use of this software
19 1.1 uch * must display the following acknowledgement:
20 1.1 uch * This product includes software developed by the NetBSD
21 1.1 uch * Foundation, Inc. and its contributors.
22 1.1 uch * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 uch * contributors may be used to endorse or promote products derived
24 1.1 uch * from this software without specific prior written permission.
25 1.1 uch *
26 1.1 uch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 uch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 uch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 uch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 uch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 uch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 uch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 uch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 uch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 uch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 uch * POSSIBILITY OF SUCH DAMAGE.
37 1.1 uch */
38 1.7 lukem
39 1.7 lukem #include <sys/cdefs.h>
40 1.15 christos __KERNEL_RCSID(0, "$NetBSD: gsfb.c,v 1.15 2006/02/04 14:54:56 christos Exp $");
41 1.1 uch
42 1.1 uch #include "debug_playstation2.h"
43 1.1 uch
44 1.1 uch #include <sys/param.h>
45 1.1 uch #include <sys/systm.h>
46 1.1 uch
47 1.1 uch #include <machine/autoconf.h>
48 1.1 uch
49 1.1 uch #include <dev/cons.h>
50 1.1 uch
51 1.1 uch #include <dev/wscons/wsconsio.h>
52 1.1 uch #include <dev/wscons/wsdisplayvar.h>
53 1.1 uch #include <dev/wscons/wscons_callbacks.h>
54 1.1 uch
55 1.1 uch #include <dev/wsfont/wsfont.h>
56 1.1 uch
57 1.1 uch #include <playstation2/ee/eevar.h>
58 1.1 uch #include <playstation2/ee/gsvar.h>
59 1.1 uch #include <playstation2/ee/gsreg.h>
60 1.1 uch #include <playstation2/ee/dmacvar.h>
61 1.1 uch #include <playstation2/ee/dmacreg.h>
62 1.1 uch
63 1.1 uch #ifdef DEBUG
64 1.1 uch #define STATIC
65 1.1 uch #else
66 1.1 uch #define STATIC static
67 1.1 uch #endif
68 1.1 uch
69 1.1 uch STATIC struct gsfb {
70 1.1 uch int initialized;
71 1.1 uch int attached;
72 1.1 uch int is_console;
73 1.1 uch const struct wsscreen_descr *screen;
74 1.1 uch struct wsdisplay_font *font;
75 1.1 uch } gsfb;
76 1.1 uch
77 1.1 uch STATIC void gsfb_dma_kick(paddr_t, size_t);
78 1.1 uch STATIC void gsfb_font_expand_psmct32(const struct wsdisplay_font *, u_int,
79 1.1 uch long, u_int32_t *);
80 1.13 perry STATIC inline void gsfb_set_cursor_pos(u_int32_t *, int, int, int, int);
81 1.1 uch
82 1.1 uch #define ATTR_FG_GET(a) (((a )>> 24) & 0xf)
83 1.1 uch #define ATTR_BG_GET(a) (((a )>> 16) & 0xf)
84 1.1 uch #define ATTR_FG_SET(x) (((x) << 24) & 0x0f000000)
85 1.1 uch #define ATTR_BG_SET(x) (((x) << 16) & 0x000f0000)
86 1.1 uch
87 1.1 uch STATIC const u_int32_t gsfb_ansi_psmct32[] = {
88 1.1 uch 0x80000000, /* black */
89 1.1 uch 0x800000aa, /* red */
90 1.1 uch 0x8000aa00, /* green */
91 1.1 uch 0x8000aaaa, /* brown */
92 1.1 uch 0x80aa0000, /* blue */
93 1.1 uch 0x80aa00aa, /* magenta */
94 1.1 uch 0x80aaaa00, /* cyan */
95 1.1 uch 0x80aaaaaa, /* white */
96 1.1 uch 0x80000000, /* black */
97 1.1 uch 0x800000ff, /* red */
98 1.1 uch 0x8000ff00, /* green */
99 1.1 uch 0x8000ffff, /* brown */
100 1.1 uch 0x80ff0000, /* blue */
101 1.1 uch 0x80ff00ff, /* magenta */
102 1.1 uch 0x80ffff00, /* cyan */
103 1.1 uch 0x80ffffff, /* black */
104 1.1 uch };
105 1.1 uch
106 1.1 uch #define TRXPOS_DXY(f, x, y) \
107 1.1 uch ({ \
108 1.1 uch f[9] = ((x) & 0x000007ff) | (((y) << 16) & 0x07ff0000); \
109 1.1 uch })
110 1.1 uch
111 1.1 uch #define TRXPOS_SY_DY(f, sy, dy) \
112 1.1 uch ({ \
113 1.1 uch f[8] = (((sy) << 16) & 0x07ff0000); \
114 1.1 uch f[9] = (((dy) << 16) & 0x07ff0000); \
115 1.1 uch })
116 1.1 uch
117 1.1 uch #define TRXPOS_DXY_SXY(f, dx, dy, sx, sy) \
118 1.1 uch ({ \
119 1.1 uch f[8] = ((((sy) << 16) & 0x07ff0000) | ((sx) & 0x000007ff)); \
120 1.1 uch f[9] = ((((dy) << 16) & 0x07ff0000) | ((dx) & 0x000007ff)); \
121 1.1 uch })
122 1.1 uch
123 1.1 uch STATIC u_int32_t gsfb_scroll_cmd_640x16[] __attribute__((__aligned__(16))) = {
124 1.1 uch 0x00008004, 0x10000000, 0x0000000e, 0x00000000,
125 1.1 uch 0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
126 1.1 uch 0x07ff0000, 0x07ff0000, 0x00000051, 0x00000000,
127 1.1 uch 0x00000280, 0x00000010, 0x00000052, 0x00000000,
128 1.1 uch 0x00000002, 0x00000000, 0x00000053, 0x00000000,
129 1.1 uch };
130 1.1 uch
131 1.1 uch STATIC u_int32_t gsfb_cursor_cmd[] __attribute__((__aligned__(16))) = {
132 1.1 uch 0x00008007, 0x10000000, 0x0000000e, 0x00000000,
133 1.1 uch 0x00000001, 0x00000000, 0x0000001a, 0x00000000,
134 1.1 uch 0x000000a4, 0x00000080, 0x00000042, 0x00000000,
135 1.1 uch 0x00000046, 0x00000000, 0x00000000, 0x00000000,
136 1.1 uch 0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
137 1.1 uch 0x00000000, 0x00000000, 0x0000000d, 0x00000000,
138 1.1 uch 0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
139 1.1 uch 0x00000000, 0x00000000, 0x00000005, 0x00000000,
140 1.1 uch };
141 1.1 uch
142 1.1 uch STATIC u_int32_t gsfb_copy_cmd_8x16[] __attribute__((__aligned__(16))) = {
143 1.1 uch 0x00008004, 0x10000000, 0x0000000e, 0x00000000,
144 1.1 uch 0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
145 1.1 uch 0x07ff07ff, 0x07ff07ff, 0x00000051, 0x00000000,
146 1.1 uch 0x00000008, 0x00000010, 0x00000052, 0x00000000,
147 1.1 uch 0x00000002, 0x00000000, 0x00000053, 0x00000000,
148 1.1 uch };
149 1.1 uch
150 1.1 uch STATIC u_int32_t gsfb_init_cmd_640x480[] __attribute__((__aligned__(16))) = {
151 1.1 uch 0x00008008, 0x10000000, 0x0000000e, 0x00000000,
152 1.1 uch 0x000a0000, 0x00000000, 0x0000004c, 0x00000000,
153 1.1 uch 0x00000096, 0x00000000, 0x0000004e, 0x00000000,
154 1.1 uch 0x02800000, 0x01e00000, 0x00000040, 0x00000000,
155 1.1 uch 0x00000006, 0x00000000, 0x00000000, 0x00000000,
156 1.1 uch 0x80000000, 0x00000000, 0x00000001, 0x00000000,
157 1.1 uch 0x00000000, 0x00000000, 0x0000000d, 0x00000000,
158 1.1 uch 0x80000000, 0x00000000, 0x00000001, 0x00000000,
159 1.1 uch 0x1e002800, 0x00000000, 0x00000005, 0x00000000,
160 1.1 uch };
161 1.1 uch
162 1.1 uch STATIC u_int32_t gsfb_load_cmd_8x16_psmct32[(6 + 32) * 4]
163 1.1 uch __attribute__((__aligned__(16))) = {
164 1.1 uch /* GIF tag + GS command */
165 1.1 uch 0x00000004, 0x10000000, 0x0000000e, 0x00000000,
166 1.1 uch 0x00000000, 0x000a0000, 0x00000050, 0x00000000,
167 1.1 uch 0x00000000, 0x00000000, 0x00000051, 0x00000000,
168 1.1 uch 0x00000008, 0x00000016, 0x00000052, 0x00000000,
169 1.1 uch 0x00000000, 0x00000000, 0x00000053, 0x00000000,
170 1.1 uch 0x00008020, 0x08000000, 0x00000000, 0x00000000,
171 1.1 uch /* Load area */
172 1.1 uch #define FONT_SCRATCH_BASE (6 * 4)
173 1.1 uch };
174 1.1 uch
175 1.1 uch #ifdef GSFB_DEBUG_MONITOR
176 1.1 uch #include <machine/stdarg.h>
177 1.1 uch STATIC const struct _gsfb_debug_window {
178 1.1 uch int start, nrow, attr;
179 1.1 uch } _gsfb_debug_window[3] = {
180 1.1 uch { 24, 2 , ATTR_BG_SET(WSCOL_BROWN) | ATTR_FG_SET(WSCOL_BLUE) },
181 1.1 uch { 26, 2 , ATTR_BG_SET(WSCOL_CYAN) | ATTR_FG_SET(WSCOL_BLUE) },
182 1.1 uch { 28, 2 , ATTR_BG_SET(WSCOL_WHITE) | ATTR_FG_SET(WSCOL_BLUE) },
183 1.1 uch };
184 1.1 uch STATIC char _gsfb_debug_buf[80 * 2];
185 1.1 uch #endif /* GSFB_DEBUG_MONITOR */
186 1.1 uch
187 1.1 uch STATIC int gsfb_match(struct device *, struct cfdata *, void *);
188 1.1 uch STATIC void gsfb_attach(struct device *, struct device *, void *);
189 1.1 uch
190 1.6 thorpej CFATTACH_DECL(gsfb, sizeof(struct device),
191 1.6 thorpej gsfb_match, gsfb_attach, NULL, NULL);
192 1.1 uch
193 1.1 uch STATIC void gsfb_hwinit(void);
194 1.1 uch STATIC int gsfb_swinit(void);
195 1.1 uch
196 1.1 uch /* console */
197 1.1 uch void gsfbcnprobe(struct consdev *);
198 1.1 uch void gsfbcninit(struct consdev *);
199 1.1 uch
200 1.1 uch /* emul ops */
201 1.1 uch STATIC void _gsfb_cursor(void *, int, int, int);
202 1.1 uch STATIC int _gsfb_mapchar(void *, int, unsigned int *);
203 1.1 uch STATIC void _gsfb_putchar(void *, int, int, u_int, long);
204 1.1 uch STATIC void _gsfb_copycols(void *, int, int, int, int);
205 1.1 uch STATIC void _gsfb_erasecols(void *, int, int, int, long);
206 1.1 uch STATIC void _gsfb_copyrows(void *, int, int, int);
207 1.1 uch STATIC void _gsfb_eraserows(void *, int, int, long);
208 1.4 junyoung STATIC int _gsfb_allocattr(void *, int, int, int, long *);
209 1.1 uch
210 1.1 uch /* access ops */
211 1.12 he STATIC int _gsfb_ioctl(void *, u_long, caddr_t, int, struct lwp *);
212 1.1 uch STATIC paddr_t _gsfb_mmap(void *, off_t, int);
213 1.1 uch STATIC int _gsfb_alloc_screen(void *, const struct wsscreen_descr *, void **,
214 1.1 uch int *, int *, long *);
215 1.1 uch STATIC void _gsfb_free_screen(void *, void *);
216 1.1 uch STATIC int _gsfb_show_screen(void *, void *, int, void (*)(void *, int, int),
217 1.1 uch void *);
218 1.1 uch STATIC void _gsfb_pollc(void *, int);
219 1.1 uch
220 1.1 uch /*
221 1.1 uch * wsdisplay attach args
222 1.1 uch * std: screen size 640 x 480, font size 8 x 16
223 1.1 uch */
224 1.1 uch #define GSFB_STD_SCREEN_WIDTH 640
225 1.1 uch #define GSFB_STD_SCREEN_HEIGHT 480
226 1.1 uch #define GSFB_STD_FONT_WIDTH 8
227 1.1 uch #define GSFB_STD_FONT_HEIGHT 16
228 1.1 uch const struct wsdisplay_emulops _gsfb_emulops = {
229 1.1 uch .cursor = _gsfb_cursor,
230 1.1 uch .mapchar = _gsfb_mapchar,
231 1.1 uch .putchar = _gsfb_putchar,
232 1.1 uch .copycols = _gsfb_copycols,
233 1.1 uch .erasecols = _gsfb_erasecols,
234 1.1 uch .copyrows = _gsfb_copyrows,
235 1.1 uch .eraserows = _gsfb_eraserows,
236 1.4 junyoung .allocattr = _gsfb_allocattr
237 1.1 uch };
238 1.1 uch
239 1.1 uch const struct wsscreen_descr _gsfb_std_screen = {
240 1.1 uch .name = "std",
241 1.1 uch .ncols = 80,
242 1.1 uch #ifdef GSFB_DEBUG_MONITOR
243 1.1 uch .nrows = 24,
244 1.1 uch #else
245 1.1 uch .nrows = 30,
246 1.1 uch #endif
247 1.1 uch .textops = &_gsfb_emulops,
248 1.1 uch .fontwidth = 8,
249 1.1 uch .fontheight = 16,
250 1.1 uch .capabilities = WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
251 1.1 uch WSSCREEN_WSCOLORS
252 1.1 uch };
253 1.1 uch
254 1.1 uch const struct wsscreen_descr *_gsfb_screen_table[] = {
255 1.1 uch &_gsfb_std_screen,
256 1.1 uch };
257 1.1 uch
258 1.1 uch struct wsscreen_list _gsfb_screen_list = {
259 1.1 uch .nscreens = sizeof(_gsfb_screen_table) /
260 1.1 uch sizeof(_gsfb_screen_table[0]),
261 1.1 uch .screens = _gsfb_screen_table
262 1.1 uch };
263 1.1 uch
264 1.1 uch struct wsdisplay_accessops _gsfb_accessops = {
265 1.1 uch .ioctl = _gsfb_ioctl,
266 1.1 uch .mmap = _gsfb_mmap,
267 1.1 uch .alloc_screen = _gsfb_alloc_screen,
268 1.1 uch .free_screen = _gsfb_free_screen,
269 1.1 uch .show_screen = _gsfb_show_screen,
270 1.1 uch .load_font = 0,
271 1.1 uch .pollc = _gsfb_pollc
272 1.1 uch };
273 1.1 uch
274 1.1 uch int
275 1.1 uch gsfb_match(struct device *parent, struct cfdata *cf, void *aux)
276 1.1 uch {
277 1.1 uch extern struct cfdriver gsfb_cd;
278 1.1 uch struct mainbus_attach_args *ma = aux;
279 1.1 uch
280 1.1 uch if (strcmp(ma->ma_name, gsfb_cd.cd_name) != 0)
281 1.1 uch return (0);
282 1.1 uch
283 1.1 uch return (!gsfb.attached);
284 1.1 uch }
285 1.1 uch
286 1.1 uch void
287 1.1 uch gsfb_attach(struct device *parent, struct device *self, void *aux)
288 1.1 uch {
289 1.1 uch struct wsemuldisplaydev_attach_args wa;
290 1.1 uch
291 1.1 uch gsfb.attached = 1;
292 1.1 uch if (!gsfb.is_console && gsfb_swinit() != 0)
293 1.1 uch return;
294 1.1 uch
295 1.1 uch printf("\n");
296 1.1 uch
297 1.1 uch wa.console = gsfb.is_console;
298 1.1 uch wa.scrdata = &_gsfb_screen_list;
299 1.1 uch wa.accessops = &_gsfb_accessops;
300 1.1 uch wa.accesscookie = &gsfb;
301 1.1 uch
302 1.1 uch config_found(self, &wa, wsdisplaydevprint);
303 1.1 uch }
304 1.1 uch
305 1.1 uch /*
306 1.1 uch * console
307 1.1 uch */
308 1.1 uch void
309 1.1 uch gsfbcnprobe(struct consdev *cndev)
310 1.1 uch {
311 1.1 uch
312 1.1 uch cndev->cn_pri = CN_INTERNAL;
313 1.1 uch }
314 1.1 uch
315 1.1 uch void
316 1.1 uch gsfbcninit(struct consdev *cndev)
317 1.1 uch {
318 1.1 uch paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_init_cmd_640x480);
319 1.15 christos u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
320 1.15 christos long defattr = ATTR_BG_SET(WS_DEFAULT_BG) | ATTR_FG_SET(WS_DEFAULT_FG);
321 1.1 uch
322 1.1 uch gsfb.is_console = 1;
323 1.1 uch
324 1.1 uch gsfb_hwinit();
325 1.1 uch gsfb_swinit();
326 1.1 uch
327 1.15 christos /* Set the screen to the default background color at boot */
328 1.15 christos buf[28] = gsfb_ansi_psmct32[ATTR_BG_GET(defattr)];
329 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_init_cmd_640x480);
330 1.1 uch #ifdef GSFB_DEBUG_MONITOR
331 1.1 uch {
332 1.1 uch const struct _gsfb_debug_window *win;
333 1.1 uch int i;
334 1.1 uch
335 1.1 uch for (i = 0; i < 3; i++) {
336 1.1 uch win = &_gsfb_debug_window[i];
337 1.1 uch _gsfb_eraserows(0, win->start, win->nrow, win->attr);
338 1.1 uch }
339 1.1 uch }
340 1.1 uch #endif /* GSFB_DEBUG_MONITOR */
341 1.1 uch
342 1.1 uch wsdisplay_cnattach(&_gsfb_std_screen, &gsfb, 0, 0, defattr);
343 1.1 uch }
344 1.1 uch
345 1.1 uch void
346 1.1 uch gsfb_hwinit()
347 1.1 uch {
348 1.10 uch /*
349 1.10 uch gs_init(VESA_1A) hang up on SCPH-50000.
350 1.10 uch use bootloader's setting.
351 1.10 uch EN1 | CRTMOD | MMOD | AMOD | ALP(all 1.0)
352 1.10 uch */
353 1.10 uch _reg_write_8(GS_S_PMODE_REG, 0xffa5);
354 1.10 uch
355 1.1 uch dmac_init();
356 1.1 uch
357 1.1 uch /* reset GIF channel DMA */
358 1.1 uch _reg_write_4(D2_QWC_REG, 0);
359 1.1 uch _reg_write_4(D2_MADR_REG, 0);
360 1.1 uch _reg_write_4(D2_TADR_REG, 0);
361 1.1 uch _reg_write_4(D2_CHCR_REG, 0);
362 1.1 uch }
363 1.1 uch
364 1.1 uch int
365 1.1 uch gsfb_swinit()
366 1.1 uch {
367 1.1 uch int font;
368 1.1 uch
369 1.1 uch wsfont_init();
370 1.2 ad font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
371 1.2 ad WSDISPLAY_FONTORDER_L2R);
372 1.1 uch if (font < 0)
373 1.1 uch return (1);
374 1.1 uch
375 1.2 ad if (wsfont_lock(font, &gsfb.font))
376 1.1 uch return (1);
377 1.1 uch
378 1.1 uch gsfb.screen = &_gsfb_std_screen;
379 1.1 uch gsfb.initialized = 1;
380 1.1 uch
381 1.1 uch return (0);
382 1.1 uch }
383 1.1 uch
384 1.1 uch /*
385 1.1 uch * wsdisplay
386 1.1 uch */
387 1.1 uch void
388 1.1 uch _gsfb_cursor(void *cookie, int on, int row, int col)
389 1.1 uch {
390 1.1 uch paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_cursor_cmd);
391 1.1 uch u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
392 1.1 uch struct wsdisplay_font *font = gsfb.font;
393 1.1 uch
394 1.1 uch gsfb_set_cursor_pos(buf, col, row, font->fontwidth, font->fontheight);
395 1.1 uch
396 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_cursor_cmd);
397 1.1 uch }
398 1.1 uch
399 1.13 perry inline void
400 1.1 uch gsfb_set_cursor_pos(u_int32_t *p, int x, int y, int w, int h)
401 1.1 uch {
402 1.1 uch
403 1.1 uch x *= w;
404 1.1 uch y *= h;
405 1.1 uch p[20] = ((x << 4) & 0xffff) | ((y << 20) & 0xffff0000);
406 1.14 martin p[28] = (((x + w) << 4) & 0xffff) | (((y + h) << 20) & 0xffff0000);
407 1.1 uch }
408 1.1 uch
409 1.1 uch int
410 1.1 uch _gsfb_mapchar(void *cookie, int c, unsigned int *cp)
411 1.1 uch {
412 1.1 uch struct wsdisplay_font *font = gsfb.font;
413 1.1 uch
414 1.1 uch if (font->encoding != WSDISPLAY_FONTENC_ISO)
415 1.1 uch if ((c = wsfont_map_unichar(font, c)) < 0)
416 1.1 uch goto nomap;
417 1.1 uch
418 1.1 uch if (c < font->firstchar || c >= font->firstchar + font->numchars)
419 1.1 uch goto nomap;
420 1.1 uch
421 1.1 uch *cp = c;
422 1.1 uch return (5);
423 1.1 uch
424 1.1 uch nomap:
425 1.1 uch *cp = ' ';
426 1.1 uch return (0);
427 1.1 uch }
428 1.1 uch
429 1.1 uch void
430 1.1 uch _gsfb_putchar(void *cookie, int row, int col, u_int uc, long attr)
431 1.1 uch {
432 1.1 uch paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_load_cmd_8x16_psmct32);
433 1.1 uch u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
434 1.1 uch struct wsdisplay_font *font = gsfb.font;
435 1.1 uch
436 1.1 uch /* copy font data to DMA region */
437 1.1 uch gsfb_font_expand_psmct32(font, uc, attr, &buf[FONT_SCRATCH_BASE]);
438 1.1 uch
439 1.1 uch /* set destination position */
440 1.1 uch TRXPOS_DXY(buf, col * font->fontwidth, row * font->fontheight);
441 1.1 uch
442 1.1 uch /* kick to GIF */
443 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_load_cmd_8x16_psmct32);
444 1.1 uch }
445 1.1 uch
446 1.1 uch void
447 1.1 uch _gsfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
448 1.1 uch {
449 1.1 uch paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_copy_cmd_8x16);
450 1.1 uch u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
451 1.1 uch int y = gsfb.font->fontheight * row;
452 1.1 uch int w = gsfb.font->fontwidth;
453 1.1 uch int i;
454 1.1 uch
455 1.1 uch if (dstcol > srccol) {
456 1.1 uch for (i = ncols - 1; i >= 0; i--) {
457 1.1 uch TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
458 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
459 1.1 uch }
460 1.1 uch } else {
461 1.1 uch for (i = 0; i < ncols; i++) {
462 1.1 uch TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
463 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
464 1.1 uch }
465 1.1 uch }
466 1.1 uch }
467 1.1 uch
468 1.1 uch void
469 1.1 uch _gsfb_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
470 1.1 uch {
471 1.1 uch int i;
472 1.1 uch
473 1.1 uch for (i = 0; i < ncols; i++)
474 1.1 uch _gsfb_putchar(cookie, row, startcol + i, ' ', attr);
475 1.1 uch }
476 1.1 uch
477 1.1 uch void
478 1.1 uch _gsfb_copyrows(void *cookie, int src, int dst, int num)
479 1.1 uch {
480 1.1 uch paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_scroll_cmd_640x16);
481 1.1 uch u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
482 1.1 uch int i;
483 1.1 uch int h = gsfb.font->fontheight;
484 1.1 uch
485 1.1 uch if (dst > src) {
486 1.1 uch for (i = num - 1; i >= 0; i--) {
487 1.1 uch TRXPOS_SY_DY(cmd, (src + i) * h, (dst + i) * h);
488 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
489 1.1 uch }
490 1.1 uch } else {
491 1.1 uch for (i = 0; i < num; i++) {
492 1.1 uch TRXPOS_SY_DY(cmd, (src + i) * h, (dst + i) * h);
493 1.1 uch gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
494 1.1 uch }
495 1.1 uch }
496 1.1 uch }
497 1.1 uch
498 1.1 uch void
499 1.1 uch _gsfb_eraserows(void *cookie, int row, int nrow, long attr)
500 1.1 uch {
501 1.1 uch int i, j;
502 1.1 uch
503 1.1 uch for (j = 0; j < nrow; j++)
504 1.1 uch for (i = 0; i < gsfb.screen->ncols; i++)
505 1.1 uch _gsfb_putchar(cookie, row + j, i, ' ', attr);
506 1.1 uch }
507 1.1 uch
508 1.1 uch int
509 1.4 junyoung _gsfb_allocattr(void *cookie, int fg, int bg, int flags, long *attr)
510 1.1 uch {
511 1.1 uch
512 1.1 uch if ((flags & WSATTR_BLINK) != 0)
513 1.1 uch return (EINVAL);
514 1.1 uch
515 1.1 uch if ((flags & WSATTR_WSCOLORS) == 0) {
516 1.15 christos fg = WS_DEFAULT_FG;
517 1.15 christos bg = WS_DEFAULT_BG;
518 1.1 uch }
519 1.1 uch
520 1.1 uch if ((flags & WSATTR_HILIT) != 0)
521 1.1 uch fg += 8;
522 1.1 uch
523 1.1 uch flags = (flags & WSATTR_UNDERLINE) ? 1 : 0;
524 1.1 uch
525 1.1 uch
526 1.1 uch *attr = ATTR_BG_SET(bg) | ATTR_FG_SET(fg) | flags;
527 1.1 uch
528 1.1 uch return (0);
529 1.1 uch }
530 1.1 uch
531 1.1 uch int
532 1.12 he _gsfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct lwp *l)
533 1.1 uch {
534 1.1 uch
535 1.3 atatat return (EPASSTHROUGH); /* Inappropriate ioctl for device */
536 1.1 uch }
537 1.1 uch
538 1.1 uch paddr_t
539 1.1 uch _gsfb_mmap(void *v, off_t offset, int prot)
540 1.1 uch {
541 1.1 uch
542 1.9 shin return (-1); /* can't mmap */
543 1.1 uch }
544 1.1 uch
545 1.1 uch int
546 1.1 uch _gsfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
547 1.1 uch int *curxp, int *curyp, long *attrp)
548 1.1 uch {
549 1.1 uch
550 1.15 christos *attrp = ATTR_BG_SET(WS_DEFAULT_BG) | ATTR_FG_SET(WS_DEFAULT_FG);
551 1.1 uch
552 1.1 uch return (0);
553 1.1 uch }
554 1.1 uch
555 1.1 uch void
556 1.1 uch _gsfb_free_screen(void *v, void *cookie)
557 1.1 uch {
558 1.1 uch }
559 1.1 uch
560 1.1 uch int
561 1.1 uch _gsfb_show_screen(void *v, void *cookie, int waitok,
562 1.1 uch void (*cb)(void *, int, int), void *cbarg)
563 1.1 uch {
564 1.1 uch
565 1.1 uch return (0);
566 1.1 uch }
567 1.1 uch
568 1.1 uch void
569 1.1 uch _gsfb_pollc(void *v, int on)
570 1.1 uch {
571 1.1 uch
572 1.1 uch }
573 1.1 uch
574 1.1 uch /*
575 1.1 uch * font expansion
576 1.1 uch * PSMCT32 only
577 1.1 uch */
578 1.1 uch void
579 1.1 uch gsfb_font_expand_psmct32(const struct wsdisplay_font *font, u_int c, long attr,
580 1.1 uch u_int32_t *buf)
581 1.1 uch {
582 1.1 uch u_int32_t fg, bg;
583 1.1 uch u_int8_t *bitmap;
584 1.1 uch int i, j;
585 1.1 uch
586 1.1 uch KDASSERT(((u_int32_t)buf & 15) == 0);
587 1.1 uch
588 1.1 uch fg = gsfb_ansi_psmct32[ATTR_FG_GET(attr)];
589 1.1 uch bg = gsfb_ansi_psmct32[ATTR_BG_GET(attr)];
590 1.1 uch
591 1.1 uch bitmap = (u_int8_t *)font->data + (c - font->firstchar) *
592 1.1 uch font->fontheight * font->stride;
593 1.1 uch for (i = 0; i < font->fontheight; i++, bitmap++) {
594 1.1 uch u_int32_t b = *bitmap;
595 1.1 uch for (j = 0; j < font->fontwidth; j++, b <<= 1)
596 1.1 uch *buf++ = (b & 0x80) ? fg : bg;
597 1.1 uch }
598 1.1 uch }
599 1.1 uch
600 1.1 uch void
601 1.1 uch gsfb_dma_kick(paddr_t addr, size_t size)
602 1.1 uch {
603 1.1 uch /* Wait for previous DMA request complete */
604 1.1 uch while (_reg_read_4(D2_QWC_REG))
605 1.1 uch ;
606 1.1 uch
607 1.1 uch /* Wait until GS FIFO empty */
608 1.1 uch while ((_reg_read_8(GS_S_CSR_REG) & (3 << 14)) != (1 << 14))
609 1.1 uch ;
610 1.1 uch
611 1.1 uch /* wait for DMA complete */
612 1.1 uch dmac_bus_poll(D_CH2_GIF);
613 1.1 uch
614 1.1 uch /* transfer addr */
615 1.1 uch _reg_write_4(D2_MADR_REG, addr);
616 1.1 uch /* transfer data size (unit qword) */
617 1.1 uch _reg_write_4(D2_QWC_REG, bytetoqwc(size));
618 1.1 uch
619 1.1 uch /* kick DMA (normal-mode) */
620 1.1 uch dmac_chcr_write(D_CH2_GIF, D_CHCR_STR);
621 1.1 uch }
622 1.1 uch
623 1.1 uch #ifdef GSFB_DEBUG_MONITOR
624 1.1 uch void
625 1.1 uch __gsfb_print(int window, const char *fmt, ...)
626 1.1 uch {
627 1.1 uch const struct _gsfb_debug_window *win;
628 1.1 uch int i, s, x, y, n, a;
629 1.1 uch u_int c;
630 1.1 uch va_list ap;
631 1.1 uch
632 1.1 uch if (!gsfb.initialized)
633 1.1 uch return;
634 1.1 uch
635 1.1 uch s = _intr_suspend();
636 1.1 uch win = &_gsfb_debug_window[window];
637 1.1 uch x = 0;
638 1.1 uch y = win->start;
639 1.1 uch n = win->nrow * 80;
640 1.1 uch a = win->attr;
641 1.1 uch
642 1.1 uch va_start(ap, fmt);
643 1.1 uch vsnprintf(_gsfb_debug_buf, n, fmt, ap);
644 1.1 uch va_end(ap);
645 1.1 uch
646 1.1 uch _gsfb_eraserows(0, y, win->nrow, a);
647 1.1 uch
648 1.1 uch for (i = 0; i < n &&
649 1.1 uch (c = (u_int)_gsfb_debug_buf[i] & 0x7f) != 0; i++) {
650 1.1 uch if (c == '\n')
651 1.1 uch x = 0, y++;
652 1.1 uch else
653 1.1 uch _gsfb_putchar(0, y, x++, c, a);
654 1.1 uch }
655 1.1 uch
656 1.1 uch _intr_resume(s);
657 1.1 uch }
658 1.1 uch
659 1.1 uch void
660 1.1 uch __gsfb_print_hex(int a0, int a1, int a2, int a3)
661 1.1 uch {
662 1.1 uch __gsfb_print(2, "a0=%08x a1=%08x a2=%08x a3=%08x",
663 1.1 uch a0, a1, a2, a3);
664 1.1 uch }
665 1.1 uch #endif /* GSFB_DEBUG_MONITOR */
666