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