machfb.c revision 1.14.2.5 1 1.14.2.5 skrll /* $NetBSD: machfb.c,v 1.14.2.5 2005/01/17 19:31:25 skrll Exp $ */
2 1.1 junyoung
3 1.1 junyoung /*
4 1.1 junyoung * Copyright (c) 2002 Bang Jun-Young
5 1.1 junyoung * All rights reserved.
6 1.1 junyoung *
7 1.1 junyoung * Redistribution and use in source and binary forms, with or without
8 1.1 junyoung * modification, are permitted provided that the following conditions
9 1.1 junyoung * are met:
10 1.1 junyoung * 1. Redistributions of source code must retain the above copyright
11 1.1 junyoung * notice, this list of conditions and the following disclaimer.
12 1.1 junyoung * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 junyoung * notice, this list of conditions and the following disclaimer in the
14 1.1 junyoung * documentation and/or other materials provided with the distribution.
15 1.1 junyoung * 3. The name of the author may not be used to endorse or promote products
16 1.10 junyoung * derived from this software without specific prior written permission.
17 1.1 junyoung *
18 1.1 junyoung * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 junyoung * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 junyoung * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 junyoung * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 junyoung * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.1 junyoung * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 junyoung * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 junyoung * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 junyoung * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.1 junyoung * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 junyoung */
29 1.1 junyoung
30 1.1 junyoung /*
31 1.1 junyoung * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide.
32 1.1 junyoung */
33 1.1 junyoung
34 1.1 junyoung #include <sys/cdefs.h>
35 1.14.2.5 skrll __KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.14.2.5 2005/01/17 19:31:25 skrll Exp $");
36 1.1 junyoung
37 1.1 junyoung #include <sys/param.h>
38 1.1 junyoung #include <sys/systm.h>
39 1.1 junyoung #include <sys/kernel.h>
40 1.1 junyoung #include <sys/device.h>
41 1.1 junyoung #include <sys/malloc.h>
42 1.1 junyoung #include <sys/callout.h>
43 1.1 junyoung
44 1.3 martin #ifdef __sparc__
45 1.14.2.2 skrll #include <machine/promlib.h>
46 1.3 martin #endif
47 1.3 martin
48 1.1 junyoung #include <dev/ic/videomode.h>
49 1.1 junyoung
50 1.1 junyoung #include <dev/pci/pcivar.h>
51 1.1 junyoung #include <dev/pci/pcireg.h>
52 1.1 junyoung #include <dev/pci/pcidevs.h>
53 1.1 junyoung #include <dev/pci/pciio.h>
54 1.1 junyoung #include <dev/pci/machfbreg.h>
55 1.1 junyoung
56 1.1 junyoung #include <dev/wscons/wsdisplayvar.h>
57 1.1 junyoung #include <dev/wscons/wsconsio.h>
58 1.1 junyoung #include <dev/wsfont/wsfont.h>
59 1.1 junyoung #include <dev/rasops/rasops.h>
60 1.1 junyoung
61 1.14.2.5 skrll #include "opt_wsemul.h"
62 1.14.2.5 skrll
63 1.1 junyoung #define MACH64_REG_SIZE 1024
64 1.3 martin #define MACH64_REG_OFF 0x7ffc00
65 1.1 junyoung
66 1.1 junyoung #define NBARS 3 /* number of Mach64 PCI BARs */
67 1.1 junyoung
68 1.1 junyoung struct vga_bar {
69 1.1 junyoung bus_addr_t vb_base;
70 1.1 junyoung bus_size_t vb_size;
71 1.1 junyoung pcireg_t vb_type;
72 1.1 junyoung int vb_flags;
73 1.1 junyoung };
74 1.1 junyoung
75 1.1 junyoung struct mach64_softc {
76 1.1 junyoung struct device sc_dev;
77 1.1 junyoung pci_chipset_tag_t sc_pc;
78 1.1 junyoung pcitag_t sc_pcitag;
79 1.1 junyoung
80 1.1 junyoung struct vga_bar sc_bars[NBARS];
81 1.1 junyoung struct vga_bar sc_rom;
82 1.1 junyoung
83 1.1 junyoung #define sc_aperbase sc_bars[0].vb_base
84 1.1 junyoung #define sc_apersize sc_bars[0].vb_size
85 1.1 junyoung
86 1.1 junyoung #define sc_iobase sc_bars[1].vb_base
87 1.1 junyoung #define sc_iosize sc_bars[1].vb_size
88 1.1 junyoung
89 1.1 junyoung #define sc_regbase sc_bars[2].vb_base
90 1.1 junyoung #define sc_regsize sc_bars[2].vb_size
91 1.1 junyoung
92 1.4 junyoung bus_space_tag_t sc_regt;
93 1.3 martin bus_space_tag_t sc_memt;
94 1.4 junyoung bus_space_handle_t sc_regh;
95 1.1 junyoung bus_space_handle_t sc_memh;
96 1.1 junyoung
97 1.1 junyoung size_t memsize;
98 1.1 junyoung int memtype;
99 1.1 junyoung
100 1.1 junyoung int has_dsp;
101 1.1 junyoung int bits_per_pixel;
102 1.1 junyoung int max_x, max_y;
103 1.1 junyoung int virt_x, virt_y;
104 1.1 junyoung int color_depth;
105 1.1 junyoung
106 1.1 junyoung int mem_freq;
107 1.1 junyoung int ramdac_freq;
108 1.1 junyoung int ref_freq;
109 1.1 junyoung
110 1.1 junyoung int ref_div;
111 1.1 junyoung int log2_vclk_post_div;
112 1.1 junyoung int vclk_post_div;
113 1.1 junyoung int vclk_fb_div;
114 1.1 junyoung int mclk_post_div;
115 1.1 junyoung int mclk_fb_div;
116 1.1 junyoung
117 1.1 junyoung struct mach64screen *wanted;
118 1.1 junyoung struct mach64screen *active;
119 1.1 junyoung void (*switchcb)(void *, int, int);
120 1.1 junyoung void *switchcbarg;
121 1.1 junyoung struct callout switch_callout;
122 1.1 junyoung LIST_HEAD(, mach64screen) screens;
123 1.1 junyoung const struct wsscreen_descr *currenttype;
124 1.14.2.5 skrll u_char sc_cmap_red[256];
125 1.14.2.5 skrll u_char sc_cmap_green[256];
126 1.14.2.5 skrll u_char sc_cmap_blue[256];
127 1.14.2.5 skrll int sc_dacw;
128 1.1 junyoung };
129 1.1 junyoung
130 1.1 junyoung struct mach64screen {
131 1.7 martin struct rasops_info ri;
132 1.1 junyoung LIST_ENTRY(mach64screen) next;
133 1.1 junyoung struct mach64_softc *sc;
134 1.1 junyoung const struct wsscreen_descr *type;
135 1.1 junyoung int active;
136 1.1 junyoung u_int16_t *mem;
137 1.1 junyoung int dispoffset;
138 1.1 junyoung int mindispoffset;
139 1.1 junyoung int maxdispoffset;
140 1.1 junyoung
141 1.1 junyoung int cursoron;
142 1.1 junyoung int cursorcol;
143 1.1 junyoung int cursorrow;
144 1.1 junyoung u_int16_t cursortmp;
145 1.1 junyoung };
146 1.1 junyoung
147 1.1 junyoung struct mach64_crtcregs {
148 1.1 junyoung u_int32_t h_total_disp;
149 1.1 junyoung u_int32_t h_sync_strt_wid;
150 1.1 junyoung u_int32_t v_total_disp;
151 1.1 junyoung u_int32_t v_sync_strt_wid;
152 1.1 junyoung u_int32_t gen_cntl;
153 1.1 junyoung u_int32_t clock_cntl;
154 1.1 junyoung u_int32_t color_depth;
155 1.1 junyoung u_int32_t dot_clock;
156 1.1 junyoung };
157 1.1 junyoung
158 1.1 junyoung struct {
159 1.1 junyoung u_int16_t chip_id;
160 1.1 junyoung u_int32_t ramdac_freq;
161 1.1 junyoung } mach64_info[] = {
162 1.1 junyoung { PCI_PRODUCT_ATI_MACH64_CT, 135000 },
163 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_PRO_AGP, 230000 },
164 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_PRO_AGP1X, 230000 },
165 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_PRO_PCI_B, 230000 },
166 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_XL_AGP, 230000 },
167 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_PRO_PCI_P, 230000 },
168 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_PRO_PCI_L, 230000 },
169 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_XL_PCI, 230000 },
170 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_II, 135000 },
171 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_IIP, 200000 },
172 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_IIC_PCI, 230000 },
173 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_IIC_AGP_B, 230000 },
174 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_IIC_AGP_P, 230000 },
175 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
176 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 },
177 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 },
178 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_LT, 230000 },
179 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
180 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 },
181 1.1 junyoung { PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
182 1.1 junyoung { PCI_PRODUCT_ATI_MACH64_VT, 170000 },
183 1.1 junyoung { PCI_PRODUCT_ATI_MACH64_VTB, 200000 },
184 1.1 junyoung { PCI_PRODUCT_ATI_MACH64_VT4, 230000 }
185 1.1 junyoung };
186 1.1 junyoung
187 1.1 junyoung static int mach64_chip_id, mach64_chip_rev;
188 1.1 junyoung static struct videomode default_mode;
189 1.1 junyoung static struct mach64screen mach64_console_screen;
190 1.1 junyoung
191 1.1 junyoung static char *mach64_memtype_names[] = {
192 1.1 junyoung "(N/A)", "DRAM", "EDO DRAM", "EDO DRAM", "SDRAM", "SGRAM", "WRAM",
193 1.1 junyoung "(unknown type)"
194 1.1 junyoung };
195 1.1 junyoung
196 1.1 junyoung struct videomode mach64_modes[] = {
197 1.1 junyoung /* 640x400 @ 70 Hz, 31.5 kHz */
198 1.1 junyoung { 25175, 640, 664, 760, 800, 400, 409, 411, 450, 0 },
199 1.1 junyoung /* 640x480 @ 72 Hz, 36.5 kHz */
200 1.1 junyoung { 25175, 640, 664, 760, 800, 480, 491, 493, 525, 0 },
201 1.1 junyoung /* 800x600 @ 72 Hz, 48.0 kHz */
202 1.1 junyoung { 50000, 800, 856, 976, 1040, 600, 637, 643, 666,
203 1.1 junyoung VID_PHSYNC | VID_PVSYNC },
204 1.1 junyoung /* 1024x768 @ 70 Hz, 56.5 kHz */
205 1.1 junyoung { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806,
206 1.1 junyoung VID_NHSYNC | VID_NVSYNC },
207 1.1 junyoung /* 1152x864 @ 70 Hz, 62.4 kHz */
208 1.1 junyoung { 92000, 1152, 1208, 1368, 1474, 864, 865, 875, 895, 0 },
209 1.1 junyoung /* 1280x1024 @ 70 Hz, 74.59 kHz */
210 1.1 junyoung { 126500, 1280, 1312, 1472, 1696, 1024, 1032, 1040, 1068,
211 1.1 junyoung VID_NHSYNC | VID_NVSYNC }
212 1.1 junyoung };
213 1.1 junyoung
214 1.14.2.5 skrll /* Macallan: let the terminal emulator program the palette, it should be in the softc anyway */
215 1.14.2.5 skrll #if 1
216 1.1 junyoung /* FIXME values are wrong! */
217 1.1 junyoung const u_char mach64_cmap[16 * 3] = {
218 1.1 junyoung 0x00, 0x00, 0x00, /* black */
219 1.1 junyoung 0x7f, 0x00, 0x00, /* red */
220 1.1 junyoung 0x00, 0x7f, 0x00, /* green */
221 1.1 junyoung 0x7f, 0x7f, 0x00, /* brown */
222 1.1 junyoung 0x00, 0x00, 0x7f, /* blue */
223 1.1 junyoung 0x7f, 0x00, 0x7f, /* magenta */
224 1.1 junyoung 0x00, 0x7f, 0x7f, /* cyan */
225 1.14.2.5 skrll 0xc8, 0xc8, 0xc8, /* white */
226 1.1 junyoung
227 1.1 junyoung 0x7f, 0x7f, 0x7f, /* black */
228 1.1 junyoung 0xff, 0x00, 0x00, /* red */
229 1.1 junyoung 0x00, 0xff, 0x00, /* green */
230 1.1 junyoung 0xff, 0xff, 0x00, /* brown */
231 1.1 junyoung 0x00, 0x00, 0xff, /* blue */
232 1.1 junyoung 0xff, 0x00, 0xff, /* magenta */
233 1.1 junyoung 0x00, 0xff, 0xff, /* cyan */
234 1.1 junyoung 0xff, 0xff, 0xff, /* white */
235 1.1 junyoung };
236 1.14.2.5 skrll #endif
237 1.14.2.5 skrll
238 1.14.2.5 skrll #ifdef WSEMUL_VT100
239 1.14.2.5 skrll extern const u_char rasops_cmap[768];
240 1.14.2.5 skrll #endif
241 1.1 junyoung
242 1.1 junyoung int mach64_match(struct device *, struct cfdata *, void *);
243 1.1 junyoung void mach64_attach(struct device *, struct device *, void *);
244 1.1 junyoung
245 1.1 junyoung CFATTACH_DECL(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
246 1.1 junyoung NULL, NULL);
247 1.1 junyoung
248 1.3 martin void mach64_init(struct mach64_softc *);
249 1.1 junyoung int mach64_get_memsize(struct mach64_softc *);
250 1.1 junyoung int mach64_get_max_ramdac(struct mach64_softc *);
251 1.1 junyoung void mach64_get_mode(struct mach64_softc *, struct videomode *);
252 1.1 junyoung int mach64_calc_crtcregs(struct mach64_softc *, struct mach64_crtcregs *,
253 1.1 junyoung struct videomode *);
254 1.1 junyoung void mach64_set_crtcregs(struct mach64_softc *, struct mach64_crtcregs *);
255 1.1 junyoung int mach64_modeswitch(struct mach64_softc *, struct videomode *);
256 1.1 junyoung void mach64_set_dsp(struct mach64_softc *);
257 1.1 junyoung void mach64_set_pll(struct mach64_softc *, int);
258 1.1 junyoung void mach64_reset_engine(struct mach64_softc *);
259 1.1 junyoung void mach64_init_engine(struct mach64_softc *);
260 1.1 junyoung void mach64_adjust_frame(struct mach64_softc *, int, int);
261 1.1 junyoung void mach64_init_lut(struct mach64_softc *);
262 1.1 junyoung void mach64_switch_screen(struct mach64_softc *);
263 1.1 junyoung void mach64_init_screen(struct mach64_softc *, struct mach64screen *,
264 1.6 junyoung const struct wsscreen_descr *, int, long *, int);
265 1.1 junyoung void mach64_restore_screen(struct mach64screen *,
266 1.1 junyoung const struct wsscreen_descr *, u_int16_t *);
267 1.6 junyoung int mach64_set_screentype(struct mach64_softc *,
268 1.1 junyoung const struct wsscreen_descr *);
269 1.5 junyoung int mach64_is_console(struct pci_attach_args *);
270 1.1 junyoung
271 1.1 junyoung void mach64_cursor(void *, int, int, int);
272 1.1 junyoung int mach64_mapchar(void *, int, u_int *);
273 1.1 junyoung void mach64_putchar(void *, int, int, u_int, long);
274 1.1 junyoung void mach64_copycols(void *, int, int, int, int);
275 1.1 junyoung void mach64_erasecols(void *, int, int, int, long);
276 1.1 junyoung void mach64_copyrows(void *, int, int, int);
277 1.1 junyoung void mach64_eraserows(void *, int, int, long);
278 1.1 junyoung int mach64_allocattr(void *, int, int, int, long *);
279 1.1 junyoung
280 1.14.2.5 skrll void mach64_scroll(void *, void *, int);
281 1.14.2.5 skrll
282 1.14.2.5 skrll int mach64_putcmap(struct mach64_softc *, struct wsdisplay_cmap *);
283 1.14.2.5 skrll int mach64_getcmap(struct mach64_softc *, struct wsdisplay_cmap *);
284 1.14.2.5 skrll int mach64_putpalreg(struct mach64_softc *, uint8_t, uint8_t, uint8_t, uint8_t);
285 1.14.2.5 skrll void mach64_bitblt(struct mach64_softc *, int, int, int, int, int, int, int, int) ;
286 1.14.2.5 skrll void mach64_rectfill(struct mach64_softc *, int, int, int, int, int);
287 1.14.2.5 skrll void mach64_showpal(struct mach64_softc *);
288 1.14.2.5 skrll
289 1.7 martin #if 0
290 1.1 junyoung const struct wsdisplay_emulops mach64_emulops = {
291 1.1 junyoung mach64_cursor,
292 1.1 junyoung mach64_mapchar,
293 1.1 junyoung mach64_putchar,
294 1.1 junyoung mach64_copycols,
295 1.1 junyoung mach64_erasecols,
296 1.1 junyoung mach64_copyrows,
297 1.1 junyoung mach64_eraserows,
298 1.1 junyoung mach64_allocattr,
299 1.1 junyoung };
300 1.7 martin #endif
301 1.1 junyoung
302 1.1 junyoung struct wsscreen_descr mach64_defaultscreen = {
303 1.1 junyoung "default",
304 1.1 junyoung 0, 0,
305 1.7 martin &mach64_console_screen.ri.ri_ops,
306 1.1 junyoung 8, 16,
307 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
308 1.1 junyoung &default_mode
309 1.1 junyoung }, mach64_80x25_screen = {
310 1.1 junyoung "80x25", 80, 25,
311 1.7 martin &mach64_console_screen.ri.ri_ops,
312 1.1 junyoung 8, 16,
313 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
314 1.1 junyoung &mach64_modes[0]
315 1.1 junyoung }, mach64_80x30_screen = {
316 1.1 junyoung "80x30", 80, 30,
317 1.7 martin &mach64_console_screen.ri.ri_ops,
318 1.1 junyoung 8, 16,
319 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
320 1.1 junyoung &mach64_modes[1]
321 1.1 junyoung }, mach64_80x40_screen = {
322 1.1 junyoung "80x40", 80, 40,
323 1.7 martin &mach64_console_screen.ri.ri_ops,
324 1.1 junyoung 8, 10,
325 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
326 1.1 junyoung &mach64_modes[0]
327 1.1 junyoung }, mach64_80x50_screen = {
328 1.1 junyoung "80x50", 80, 50,
329 1.7 martin &mach64_console_screen.ri.ri_ops,
330 1.1 junyoung 8, 8,
331 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
332 1.1 junyoung &mach64_modes[0]
333 1.1 junyoung }, mach64_100x37_screen = {
334 1.1 junyoung "100x37", 100, 37,
335 1.7 martin &mach64_console_screen.ri.ri_ops,
336 1.1 junyoung 8, 16,
337 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
338 1.1 junyoung &mach64_modes[2]
339 1.1 junyoung }, mach64_128x48_screen = {
340 1.1 junyoung "128x48", 128, 48,
341 1.7 martin &mach64_console_screen.ri.ri_ops,
342 1.1 junyoung 8, 16,
343 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
344 1.1 junyoung &mach64_modes[3]
345 1.1 junyoung }, mach64_144x54_screen = {
346 1.1 junyoung "144x54", 144, 54,
347 1.7 martin &mach64_console_screen.ri.ri_ops,
348 1.1 junyoung 8, 16,
349 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
350 1.1 junyoung &mach64_modes[4]
351 1.1 junyoung }, mach64_160x64_screen = {
352 1.1 junyoung "160x54", 160, 64,
353 1.7 martin &mach64_console_screen.ri.ri_ops,
354 1.1 junyoung 8, 16,
355 1.1 junyoung WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
356 1.1 junyoung &mach64_modes[5]
357 1.1 junyoung };
358 1.1 junyoung
359 1.1 junyoung const struct wsscreen_descr *_mach64_scrlist[] = {
360 1.1 junyoung &mach64_defaultscreen,
361 1.1 junyoung &mach64_80x25_screen,
362 1.1 junyoung &mach64_80x30_screen,
363 1.1 junyoung &mach64_80x40_screen,
364 1.1 junyoung &mach64_80x50_screen,
365 1.1 junyoung &mach64_100x37_screen,
366 1.1 junyoung &mach64_128x48_screen,
367 1.1 junyoung &mach64_144x54_screen,
368 1.1 junyoung &mach64_160x64_screen
369 1.1 junyoung };
370 1.1 junyoung
371 1.1 junyoung struct wsscreen_list mach64_screenlist = {
372 1.1 junyoung sizeof(_mach64_scrlist) / sizeof(struct wsscreen_descr *),
373 1.1 junyoung _mach64_scrlist
374 1.1 junyoung };
375 1.1 junyoung
376 1.14.2.4 skrll int mach64_ioctl(void *, u_long, caddr_t, int, struct lwp *);
377 1.1 junyoung paddr_t mach64_mmap(void *, off_t, int);
378 1.1 junyoung int mach64_alloc_screen(void *, const struct wsscreen_descr *, void **,
379 1.1 junyoung int *, int *, long *);
380 1.1 junyoung void mach64_free_screen(void *, void *);
381 1.1 junyoung int mach64_show_screen(void *, void *, int, void (*)(void *, int, int),
382 1.1 junyoung void *);
383 1.1 junyoung int mach64_load_font(void *, void *, struct wsdisplay_font *);
384 1.1 junyoung
385 1.1 junyoung struct wsdisplay_accessops mach64_accessops = {
386 1.1 junyoung mach64_ioctl,
387 1.1 junyoung mach64_mmap,
388 1.1 junyoung mach64_alloc_screen,
389 1.1 junyoung mach64_free_screen,
390 1.1 junyoung mach64_show_screen,
391 1.14.2.5 skrll NULL, /* load_font */
392 1.14.2.5 skrll NULL, /* polls */
393 1.14.2.5 skrll NULL, /* getwschar */
394 1.14.2.5 skrll NULL, /* putwschar */
395 1.14.2.5 skrll NULL, /* scroll */
396 1.14.2.5 skrll NULL, /* getborder */
397 1.14.2.5 skrll NULL /* setborder */
398 1.1 junyoung };
399 1.1 junyoung
400 1.1 junyoung /*
401 1.1 junyoung * Inline functions for getting access to register aperture.
402 1.1 junyoung */
403 1.1 junyoung static inline u_int32_t regr(struct mach64_softc *, u_int32_t);
404 1.1 junyoung static inline u_int8_t regrb(struct mach64_softc *, u_int32_t);
405 1.1 junyoung static inline void regw(struct mach64_softc *, u_int32_t, u_int32_t);
406 1.1 junyoung static inline void regwb(struct mach64_softc *, u_int32_t, u_int8_t);
407 1.1 junyoung static inline void regwb_pll(struct mach64_softc *, u_int32_t, u_int8_t);
408 1.1 junyoung
409 1.1 junyoung static inline u_int32_t
410 1.1 junyoung regr(struct mach64_softc *sc, u_int32_t index)
411 1.1 junyoung {
412 1.1 junyoung
413 1.4 junyoung return bus_space_read_4(sc->sc_regt, sc->sc_regh, index);
414 1.1 junyoung }
415 1.1 junyoung
416 1.1 junyoung static inline u_int8_t
417 1.1 junyoung regrb(struct mach64_softc *sc, u_int32_t index)
418 1.1 junyoung {
419 1.1 junyoung
420 1.4 junyoung return bus_space_read_1(sc->sc_regt, sc->sc_regh, index);
421 1.1 junyoung }
422 1.1 junyoung
423 1.1 junyoung static inline void
424 1.1 junyoung regw(struct mach64_softc *sc, u_int32_t index, u_int32_t data)
425 1.1 junyoung {
426 1.1 junyoung
427 1.4 junyoung bus_space_write_4(sc->sc_regt, sc->sc_regh, index, data);
428 1.14.2.5 skrll bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 4, BUS_SPACE_BARRIER_WRITE);
429 1.1 junyoung }
430 1.1 junyoung
431 1.1 junyoung static inline void
432 1.1 junyoung regwb(struct mach64_softc *sc, u_int32_t index, u_int8_t data)
433 1.1 junyoung {
434 1.1 junyoung
435 1.4 junyoung bus_space_write_1(sc->sc_regt, sc->sc_regh, index, data);
436 1.14.2.5 skrll bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 1, BUS_SPACE_BARRIER_WRITE);
437 1.1 junyoung }
438 1.1 junyoung
439 1.1 junyoung static inline void
440 1.1 junyoung regwb_pll(struct mach64_softc *sc, u_int32_t index, u_int8_t data)
441 1.1 junyoung {
442 1.1 junyoung
443 1.1 junyoung regwb(sc, CLOCK_CNTL + 1, (index << 2) | PLL_WR_EN);
444 1.1 junyoung regwb(sc, CLOCK_CNTL + 2, data);
445 1.1 junyoung regwb(sc, CLOCK_CNTL + 1, (index << 2) & ~PLL_WR_EN);
446 1.1 junyoung }
447 1.1 junyoung
448 1.1 junyoung static inline void
449 1.1 junyoung wait_for_fifo(struct mach64_softc *sc, u_int8_t v)
450 1.1 junyoung {
451 1.1 junyoung
452 1.1 junyoung while ((regr(sc, FIFO_STAT) & 0xffff) > (0x8000 >> v))
453 1.1 junyoung ;
454 1.1 junyoung }
455 1.1 junyoung
456 1.1 junyoung static inline void
457 1.1 junyoung wait_for_idle(struct mach64_softc *sc)
458 1.1 junyoung {
459 1.1 junyoung
460 1.1 junyoung wait_for_fifo(sc, 16);
461 1.1 junyoung while ((regr(sc, GUI_STAT) & 1) != 0)
462 1.1 junyoung ;
463 1.1 junyoung }
464 1.1 junyoung
465 1.1 junyoung int
466 1.1 junyoung mach64_match(struct device *parent, struct cfdata *match, void *aux)
467 1.1 junyoung {
468 1.1 junyoung struct pci_attach_args *pa = (struct pci_attach_args *)aux;
469 1.1 junyoung int i;
470 1.1 junyoung
471 1.1 junyoung if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
472 1.1 junyoung PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
473 1.1 junyoung return 0;
474 1.1 junyoung
475 1.1 junyoung for (i = 0; i < sizeof(mach64_info) / sizeof(mach64_info[0]); i++)
476 1.1 junyoung if (PCI_PRODUCT(pa->pa_id) == mach64_info[i].chip_id) {
477 1.1 junyoung mach64_chip_id = PCI_PRODUCT(pa->pa_id);
478 1.1 junyoung mach64_chip_rev = PCI_REVISION(pa->pa_class);
479 1.1 junyoung return 1;
480 1.1 junyoung }
481 1.1 junyoung
482 1.1 junyoung return 0;
483 1.1 junyoung }
484 1.1 junyoung
485 1.1 junyoung void
486 1.1 junyoung mach64_attach(struct device *parent, struct device *self, void *aux)
487 1.1 junyoung {
488 1.1 junyoung struct mach64_softc *sc = (void *)self;
489 1.1 junyoung struct pci_attach_args *pa = aux;
490 1.1 junyoung char devinfo[256];
491 1.1 junyoung int bar, reg, id;
492 1.1 junyoung struct wsemuldisplaydev_attach_args aa;
493 1.1 junyoung long defattr;
494 1.7 martin int setmode, console;
495 1.1 junyoung
496 1.1 junyoung sc->sc_pc = pa->pa_pc;
497 1.1 junyoung sc->sc_pcitag = pa->pa_tag;
498 1.14.2.5 skrll sc->sc_dacw=-1;
499 1.14.2.2 skrll pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
500 1.1 junyoung printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
501 1.1 junyoung
502 1.1 junyoung for (bar = 0; bar < NBARS; bar++) {
503 1.1 junyoung reg = PCI_MAPREG_START + (bar * 4);
504 1.1 junyoung sc->sc_bars[bar].vb_type = pci_mapreg_type(sc->sc_pc,
505 1.1 junyoung sc->sc_pcitag, reg);
506 1.1 junyoung (void)pci_mapreg_info(sc->sc_pc, sc->sc_pcitag, reg,
507 1.1 junyoung sc->sc_bars[bar].vb_type, &sc->sc_bars[bar].vb_base,
508 1.1 junyoung &sc->sc_bars[bar].vb_size, &sc->sc_bars[bar].vb_flags);
509 1.1 junyoung }
510 1.3 martin sc->sc_memt = pa->pa_memt;
511 1.1 junyoung
512 1.3 martin mach64_init(sc);
513 1.1 junyoung
514 1.1 junyoung printf("%s: %d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
515 1.4 junyoung sc->sc_dev.dv_xname, (u_int)(sc->sc_apersize / (1024 * 1024)),
516 1.4 junyoung (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024),
517 1.4 junyoung (u_int)sc->sc_regbase);
518 1.1 junyoung
519 1.1 junyoung if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT ||
520 1.1 junyoung ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
521 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
522 1.1 junyoung (mach64_chip_rev & 0x07) == 0))
523 1.1 junyoung sc->has_dsp = 0;
524 1.1 junyoung else
525 1.1 junyoung sc->has_dsp = 1;
526 1.1 junyoung
527 1.1 junyoung sc->memsize = mach64_get_memsize(sc);
528 1.1 junyoung if (sc->memsize == 8192)
529 1.1 junyoung /* The last page is used as register aperture. */
530 1.1 junyoung sc->memsize -= 4;
531 1.1 junyoung sc->memtype = regr(sc, CONFIG_STAT0) & 0x07;
532 1.1 junyoung
533 1.1 junyoung /* XXX is there any way to calculate reference frequency from
534 1.1 junyoung known values? */
535 1.1 junyoung if (mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI)
536 1.1 junyoung sc->ref_freq = 29498;
537 1.1 junyoung else
538 1.1 junyoung sc->ref_freq = 14318;
539 1.1 junyoung
540 1.1 junyoung regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
541 1.1 junyoung sc->ref_div = regrb(sc, CLOCK_CNTL + 2);
542 1.1 junyoung regwb(sc, CLOCK_CNTL + 1, MCLK_FB_DIV << 2);
543 1.1 junyoung sc->mclk_fb_div = regrb(sc, CLOCK_CNTL + 2);
544 1.1 junyoung sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) /
545 1.1 junyoung (sc->ref_div * 2);
546 1.1 junyoung sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) /
547 1.1 junyoung (sc->mem_freq * sc->ref_div);
548 1.1 junyoung sc->ramdac_freq = mach64_get_max_ramdac(sc);
549 1.2 martin printf("%s: %ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
550 1.4 junyoung sc->sc_dev.dv_xname, (u_long)sc->memsize,
551 1.1 junyoung mach64_memtype_names[sc->memtype],
552 1.1 junyoung sc->mem_freq / 1000, sc->mem_freq % 1000,
553 1.1 junyoung sc->ramdac_freq / 1000);
554 1.1 junyoung
555 1.1 junyoung id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
556 1.1 junyoung if (id != mach64_chip_id) {
557 1.1 junyoung printf("%s: chip ID mismatch, 0x%x != 0x%x\n",
558 1.1 junyoung sc->sc_dev.dv_xname, id, mach64_chip_id);
559 1.1 junyoung return;
560 1.1 junyoung }
561 1.1 junyoung
562 1.7 martin console = mach64_is_console(pa);
563 1.7 martin
564 1.1 junyoung #ifdef __sparc__
565 1.7 martin if (console) {
566 1.7 martin mach64_get_mode(sc, &default_mode);
567 1.7 martin setmode = 0;
568 1.7 martin } else {
569 1.8 martin memcpy(&default_mode, &mach64_modes[4], sizeof(struct videomode));
570 1.7 martin setmode = 1;
571 1.7 martin }
572 1.1 junyoung #else
573 1.6 junyoung memcpy(&default_mode, &mach64_modes[0], sizeof(struct videomode));
574 1.6 junyoung setmode = 1;
575 1.1 junyoung #endif
576 1.1 junyoung
577 1.1 junyoung sc->bits_per_pixel = 8;
578 1.1 junyoung sc->virt_x = default_mode.hdisplay;
579 1.1 junyoung sc->virt_y = default_mode.vdisplay;
580 1.1 junyoung sc->max_x = sc->virt_x - 1;
581 1.1 junyoung sc->max_y = (sc->memsize * 1024) /
582 1.1 junyoung (sc->virt_x * (sc->bits_per_pixel / 8)) - 1;
583 1.1 junyoung
584 1.1 junyoung sc->color_depth = CRTC_PIX_WIDTH_8BPP;
585 1.1 junyoung
586 1.1 junyoung mach64_init_engine(sc);
587 1.1 junyoung #if 0
588 1.1 junyoung mach64_adjust_frame(0, 0);
589 1.1 junyoung if (sc->bits_per_pixel == 8)
590 1.1 junyoung mach64_init_lut(sc);
591 1.1 junyoung #endif
592 1.1 junyoung
593 1.1 junyoung printf("%s: initial resolution %dx%d at %d bpp\n", sc->sc_dev.dv_xname,
594 1.1 junyoung default_mode.hdisplay, default_mode.vdisplay,
595 1.1 junyoung sc->bits_per_pixel);
596 1.1 junyoung
597 1.7 martin mach64_console_screen.ri.ri_hw = sc;
598 1.7 martin mach64_console_screen.ri.ri_depth = sc->bits_per_pixel;
599 1.8 martin mach64_console_screen.ri.ri_bits = (void*)(u_long)sc->sc_aperbase;
600 1.7 martin mach64_console_screen.ri.ri_width = default_mode.hdisplay;
601 1.7 martin mach64_console_screen.ri.ri_height = default_mode.vdisplay;
602 1.7 martin mach64_console_screen.ri.ri_stride = mach64_console_screen.ri.ri_width;
603 1.14.2.5 skrll
604 1.14.2.5 skrll mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER;
605 1.14.2.5 skrll
606 1.14.2.5 skrll #ifdef WSEMUL_SUN
607 1.14.2.5 skrll mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER|RI_FORCEMONO;
608 1.14.2.5 skrll #endif
609 1.1 junyoung
610 1.7 martin rasops_init(&mach64_console_screen.ri, mach64_console_screen.ri.ri_height / 16,
611 1.14.2.5 skrll mach64_console_screen.ri.ri_width / 8); /* XXX width/height are nonsense */
612 1.14.2.5 skrll
613 1.14.2.5 skrll /* enable acceleration */
614 1.14.2.5 skrll mach64_console_screen.ri.ri_ops.copyrows=mach64_copyrows;
615 1.14.2.5 skrll mach64_console_screen.ri.ri_ops.eraserows=mach64_eraserows;
616 1.14.2.5 skrll mach64_console_screen.ri.ri_ops.copycols=mach64_copycols;
617 1.14.2.5 skrll mach64_console_screen.ri.ri_ops.erasecols=mach64_erasecols;
618 1.1 junyoung
619 1.7 martin mach64_defaultscreen.nrows = mach64_console_screen.ri.ri_rows;
620 1.7 martin mach64_defaultscreen.ncols = mach64_console_screen.ri.ri_cols;
621 1.1 junyoung
622 1.7 martin mach64_console_screen.ri.ri_ops.allocattr(&mach64_console_screen.ri, 0, 0, 0,
623 1.1 junyoung &defattr);
624 1.14.2.5 skrll
625 1.14.2.5 skrll /* really necessary? */
626 1.14.2.5 skrll mach64_defaultscreen.capabilities=mach64_console_screen.ri.ri_caps;
627 1.14.2.5 skrll mach64_defaultscreen.textops=&mach64_console_screen.ri.ri_ops;
628 1.14.2.5 skrll
629 1.7 martin /* Initialize fonts */
630 1.14.2.5 skrll /* XXX Macallan: shouldn't that happen /before/ we call rasops_init()? */
631 1.7 martin wsfont_init();
632 1.14.2.5 skrll
633 1.7 martin if (console) {
634 1.7 martin mach64_init_screen(sc, &mach64_console_screen,
635 1.7 martin &mach64_defaultscreen, 1, &defattr, setmode);
636 1.7 martin wsdisplay_cnattach(&mach64_defaultscreen, &mach64_console_screen.ri,
637 1.3 martin 0, 0, defattr);
638 1.7 martin }
639 1.14.2.5 skrll
640 1.14.2.5 skrll mach64_init_lut(sc);
641 1.4 junyoung
642 1.14.2.5 skrll #ifdef DEBUG
643 1.14.2.5 skrll mach64_showpal(sc);
644 1.14.2.5 skrll delay(4000000);
645 1.14.2.5 skrll #endif
646 1.1 junyoung aa.console = console;
647 1.1 junyoung aa.scrdata = &mach64_screenlist;
648 1.1 junyoung aa.accessops = &mach64_accessops;
649 1.1 junyoung aa.accesscookie = sc;
650 1.1 junyoung
651 1.1 junyoung config_found(self, &aa, wsemuldisplaydevprint);
652 1.1 junyoung }
653 1.1 junyoung
654 1.1 junyoung void
655 1.1 junyoung mach64_init_screen(struct mach64_softc *sc, struct mach64screen *scr,
656 1.6 junyoung const struct wsscreen_descr *type, int existing, long *attrp, int setmode)
657 1.1 junyoung {
658 1.1 junyoung
659 1.1 junyoung scr->sc = sc;
660 1.1 junyoung scr->type = type;
661 1.1 junyoung scr->mindispoffset = 0;
662 1.1 junyoung scr->maxdispoffset = sc->memsize * 1024;
663 1.1 junyoung scr->dispoffset = 0;
664 1.1 junyoung scr->cursorcol = 0;
665 1.1 junyoung scr->cursorrow = 0;
666 1.1 junyoung
667 1.7 martin scr->mem = (u_int16_t *)malloc(type->nrows * type->ncols * 2,
668 1.7 martin M_DEVBUF, M_WAITOK);
669 1.1 junyoung if (existing) {
670 1.1 junyoung scr->active = 1;
671 1.1 junyoung
672 1.6 junyoung if (setmode && mach64_set_screentype(sc, type)) {
673 1.1 junyoung panic("%s: failed to switch video mode",
674 1.1 junyoung sc->sc_dev.dv_xname);
675 1.1 junyoung }
676 1.1 junyoung } else {
677 1.1 junyoung scr->active = 0;
678 1.1 junyoung }
679 1.1 junyoung
680 1.1 junyoung LIST_INSERT_HEAD(&sc->screens, scr, next);
681 1.1 junyoung }
682 1.1 junyoung
683 1.1 junyoung void
684 1.3 martin mach64_init(struct mach64_softc *sc)
685 1.1 junyoung {
686 1.9 martin u_int32_t *p32, saved_value;
687 1.9 martin u_int8_t *p;
688 1.9 martin int need_swap;
689 1.4 junyoung
690 1.3 martin if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
691 1.1 junyoung BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
692 1.1 junyoung panic("%s: failed to map aperture", sc->sc_dev.dv_xname);
693 1.1 junyoung }
694 1.4 junyoung sc->sc_aperbase = (vaddr_t)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
695 1.4 junyoung
696 1.4 junyoung sc->sc_regt = sc->sc_memt;
697 1.4 junyoung bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
698 1.4 junyoung sc->sc_regsize, &sc->sc_regh);
699 1.4 junyoung sc->sc_regbase = sc->sc_aperbase + 0x7ffc00;
700 1.4 junyoung
701 1.9 martin /*
702 1.9 martin * Test wether the aperture is byte swapped or not
703 1.9 martin */
704 1.12 martin p32 = (u_int32_t*)(u_long)sc->sc_aperbase;
705 1.9 martin saved_value = *p32;
706 1.12 martin p = (u_int8_t*)(u_long)sc->sc_aperbase;
707 1.9 martin *p32 = 0x12345678;
708 1.9 martin if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78)
709 1.9 martin need_swap = 0;
710 1.9 martin else
711 1.9 martin need_swap = 1;
712 1.9 martin if (need_swap) {
713 1.9 martin sc->sc_aperbase += 0x800000;
714 1.9 martin sc->sc_apersize -= 0x800000;
715 1.9 martin }
716 1.9 martin *p32 = saved_value;
717 1.1 junyoung
718 1.1 junyoung LIST_INIT(&sc->screens);
719 1.1 junyoung sc->active = NULL;
720 1.1 junyoung sc->currenttype = &mach64_defaultscreen;
721 1.1 junyoung callout_init(&sc->switch_callout);
722 1.1 junyoung }
723 1.1 junyoung
724 1.1 junyoung int
725 1.1 junyoung mach64_get_memsize(struct mach64_softc *sc)
726 1.1 junyoung {
727 1.1 junyoung int tmp, memsize;
728 1.1 junyoung int mem_tab[] = {
729 1.1 junyoung 512, 1024, 2048, 4096, 6144, 8192, 12288, 16384
730 1.1 junyoung };
731 1.1 junyoung
732 1.1 junyoung tmp = regr(sc, MEM_CNTL);
733 1.1 junyoung if (sc->has_dsp) {
734 1.1 junyoung tmp &= 0x0000000f;
735 1.1 junyoung if (tmp < 8)
736 1.1 junyoung memsize = (tmp + 1) * 512;
737 1.1 junyoung else if (tmp < 12)
738 1.1 junyoung memsize = (tmp - 3) * 1024;
739 1.1 junyoung else
740 1.1 junyoung memsize = (tmp - 7) * 2048;
741 1.1 junyoung } else {
742 1.1 junyoung memsize = mem_tab[tmp & 0x07];
743 1.1 junyoung }
744 1.1 junyoung
745 1.1 junyoung return memsize;
746 1.1 junyoung }
747 1.1 junyoung
748 1.1 junyoung int
749 1.1 junyoung mach64_get_max_ramdac(struct mach64_softc *sc)
750 1.1 junyoung {
751 1.1 junyoung int i;
752 1.1 junyoung
753 1.1 junyoung if ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
754 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
755 1.1 junyoung (mach64_chip_rev & 0x07))
756 1.1 junyoung return 170000;
757 1.1 junyoung
758 1.1 junyoung for (i = 0; i < sizeof(mach64_info) / sizeof(mach64_info[0]); i++)
759 1.1 junyoung if (mach64_chip_id == mach64_info[i].chip_id)
760 1.1 junyoung return mach64_info[i].ramdac_freq;
761 1.1 junyoung
762 1.1 junyoung if (sc->bits_per_pixel == 8)
763 1.1 junyoung return 135000;
764 1.1 junyoung else
765 1.1 junyoung return 80000;
766 1.1 junyoung }
767 1.1 junyoung
768 1.1 junyoung void
769 1.1 junyoung mach64_get_mode(struct mach64_softc *sc, struct videomode *mode)
770 1.1 junyoung {
771 1.1 junyoung struct mach64_crtcregs crtc;
772 1.1 junyoung
773 1.1 junyoung crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP);
774 1.1 junyoung crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID);
775 1.1 junyoung crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP);
776 1.1 junyoung crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID);
777 1.1 junyoung
778 1.1 junyoung mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3;
779 1.1 junyoung mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3;
780 1.1 junyoung mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3;
781 1.1 junyoung mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) +
782 1.1 junyoung mode->hsync_start;
783 1.1 junyoung mode->vtotal = (crtc.v_total_disp & 0xffff) + 1;
784 1.1 junyoung mode->vdisplay = (crtc.v_total_disp >> 16) + 1;
785 1.1 junyoung mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1;
786 1.1 junyoung mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start;
787 1.1 junyoung
788 1.1 junyoung #ifdef MACH64_DEBUG
789 1.1 junyoung printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n",
790 1.1 junyoung mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
791 1.1 junyoung mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal);
792 1.1 junyoung #endif
793 1.1 junyoung }
794 1.1 junyoung
795 1.1 junyoung int
796 1.1 junyoung mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc,
797 1.1 junyoung struct videomode *mode)
798 1.1 junyoung {
799 1.1 junyoung
800 1.1 junyoung if (mode->dot_clock > sc->ramdac_freq)
801 1.1 junyoung /* Clock too high. */
802 1.1 junyoung return 1;
803 1.1 junyoung
804 1.1 junyoung crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) |
805 1.1 junyoung ((mode->htotal >> 3) - 1);
806 1.1 junyoung crtc->h_sync_strt_wid =
807 1.1 junyoung (((mode->hsync_end - mode->hsync_start) >> 3) << 16) |
808 1.1 junyoung ((mode->hsync_start >> 3) - 1);
809 1.1 junyoung
810 1.1 junyoung crtc->v_total_disp = ((mode->vdisplay - 1) << 16) |
811 1.1 junyoung (mode->vtotal - 1);
812 1.1 junyoung crtc->v_sync_strt_wid =
813 1.1 junyoung ((mode->vsync_end - mode->vsync_start) << 16) |
814 1.1 junyoung (mode->vsync_start - 1);
815 1.1 junyoung
816 1.1 junyoung if (mode->flags & VID_NVSYNC)
817 1.1 junyoung crtc->v_sync_strt_wid |= CRTC_VSYNC_NEG;
818 1.1 junyoung
819 1.1 junyoung switch (sc->bits_per_pixel) {
820 1.1 junyoung case 8:
821 1.1 junyoung crtc->color_depth = CRTC_PIX_WIDTH_8BPP;
822 1.1 junyoung break;
823 1.1 junyoung case 16:
824 1.1 junyoung crtc->color_depth = CRTC_PIX_WIDTH_16BPP;
825 1.1 junyoung break;
826 1.1 junyoung case 32:
827 1.1 junyoung crtc->color_depth = CRTC_PIX_WIDTH_32BPP;
828 1.1 junyoung break;
829 1.1 junyoung }
830 1.1 junyoung
831 1.1 junyoung crtc->gen_cntl = 0;
832 1.1 junyoung if (mode->flags & VID_INTERLACE)
833 1.1 junyoung crtc->gen_cntl |= CRTC_INTERLACE_EN;
834 1.1 junyoung if (mode->flags & VID_CSYNC)
835 1.1 junyoung crtc->gen_cntl |= CRTC_CSYNC_EN;
836 1.1 junyoung
837 1.1 junyoung crtc->dot_clock = mode->dot_clock;
838 1.1 junyoung
839 1.1 junyoung return 0;
840 1.1 junyoung }
841 1.1 junyoung
842 1.1 junyoung void
843 1.1 junyoung mach64_set_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc)
844 1.1 junyoung {
845 1.1 junyoung
846 1.1 junyoung mach64_set_pll(sc, crtc->dot_clock);
847 1.1 junyoung
848 1.1 junyoung if (sc->has_dsp)
849 1.1 junyoung mach64_set_dsp(sc);
850 1.1 junyoung
851 1.1 junyoung regw(sc, CRTC_H_TOTAL_DISP, crtc->h_total_disp);
852 1.1 junyoung regw(sc, CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
853 1.1 junyoung regw(sc, CRTC_V_TOTAL_DISP, crtc->v_total_disp);
854 1.1 junyoung regw(sc, CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
855 1.1 junyoung
856 1.1 junyoung regw(sc, CRTC_VLINE_CRNT_VLINE, 0);
857 1.1 junyoung
858 1.1 junyoung regw(sc, CRTC_OFF_PITCH, (sc->virt_x >> 3) << 22);
859 1.1 junyoung
860 1.1 junyoung regw(sc, CRTC_GEN_CNTL, crtc->gen_cntl | crtc->color_depth |
861 1.1 junyoung CRTC_EXT_DISP_EN | CRTC_EXT_EN);
862 1.1 junyoung }
863 1.1 junyoung
864 1.1 junyoung int
865 1.1 junyoung mach64_modeswitch(struct mach64_softc *sc, struct videomode *mode)
866 1.1 junyoung {
867 1.1 junyoung struct mach64_crtcregs crtc;
868 1.1 junyoung
869 1.1 junyoung if (mach64_calc_crtcregs(sc, &crtc, mode))
870 1.1 junyoung return 1;
871 1.1 junyoung
872 1.1 junyoung mach64_set_crtcregs(sc, &crtc);
873 1.1 junyoung return 0;
874 1.1 junyoung }
875 1.1 junyoung
876 1.1 junyoung void
877 1.1 junyoung mach64_reset_engine(struct mach64_softc *sc)
878 1.1 junyoung {
879 1.1 junyoung
880 1.1 junyoung /* Reset engine.*/
881 1.1 junyoung regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE);
882 1.1 junyoung
883 1.1 junyoung /* Enable engine. */
884 1.1 junyoung regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) | GUI_ENGINE_ENABLE);
885 1.1 junyoung
886 1.1 junyoung /* Ensure engine is not locked up by clearing any FIFO or
887 1.1 junyoung host errors. */
888 1.1 junyoung regw(sc, BUS_CNTL, regr(sc, BUS_CNTL) | BUS_HOST_ERR_ACK |
889 1.1 junyoung BUS_FIFO_ERR_ACK);
890 1.1 junyoung }
891 1.1 junyoung
892 1.1 junyoung void
893 1.1 junyoung mach64_init_engine(struct mach64_softc *sc)
894 1.1 junyoung {
895 1.1 junyoung u_int32_t pitch_value;
896 1.1 junyoung
897 1.1 junyoung pitch_value = sc->virt_x;
898 1.1 junyoung
899 1.1 junyoung if (sc->bits_per_pixel == 24)
900 1.1 junyoung pitch_value *= 3;
901 1.1 junyoung
902 1.1 junyoung mach64_reset_engine(sc);
903 1.1 junyoung
904 1.1 junyoung wait_for_fifo(sc, 14);
905 1.1 junyoung
906 1.1 junyoung regw(sc, CONTEXT_MASK, 0xffffffff);
907 1.1 junyoung
908 1.1 junyoung regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22);
909 1.1 junyoung
910 1.1 junyoung regw(sc, DST_Y_X, 0);
911 1.1 junyoung regw(sc, DST_HEIGHT, 0);
912 1.1 junyoung regw(sc, DST_BRES_ERR, 0);
913 1.1 junyoung regw(sc, DST_BRES_INC, 0);
914 1.1 junyoung regw(sc, DST_BRES_DEC, 0);
915 1.1 junyoung
916 1.1 junyoung regw(sc, DST_CNTL, DST_LAST_PEL | DST_X_LEFT_TO_RIGHT |
917 1.1 junyoung DST_Y_TOP_TO_BOTTOM);
918 1.1 junyoung
919 1.1 junyoung regw(sc, SRC_OFF_PITCH, (pitch_value / 8) << 22);
920 1.1 junyoung
921 1.1 junyoung regw(sc, SRC_Y_X, 0);
922 1.1 junyoung regw(sc, SRC_HEIGHT1_WIDTH1, 1);
923 1.1 junyoung regw(sc, SRC_Y_X_START, 0);
924 1.1 junyoung regw(sc, SRC_HEIGHT2_WIDTH2, 1);
925 1.1 junyoung
926 1.1 junyoung regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
927 1.1 junyoung
928 1.1 junyoung wait_for_fifo(sc, 13);
929 1.1 junyoung regw(sc, HOST_CNTL, 0);
930 1.1 junyoung
931 1.1 junyoung regw(sc, PAT_REG0, 0);
932 1.1 junyoung regw(sc, PAT_REG1, 0);
933 1.1 junyoung regw(sc, PAT_CNTL, 0);
934 1.1 junyoung
935 1.1 junyoung regw(sc, SC_LEFT, 0);
936 1.1 junyoung regw(sc, SC_TOP, 0);
937 1.1 junyoung regw(sc, SC_BOTTOM, default_mode.vdisplay - 1);
938 1.1 junyoung regw(sc, SC_RIGHT, pitch_value - 1);
939 1.1 junyoung
940 1.1 junyoung regw(sc, DP_BKGD_CLR, 0);
941 1.1 junyoung regw(sc, DP_FRGD_CLR, 0xffffffff);
942 1.1 junyoung regw(sc, DP_WRITE_MASK, 0xffffffff);
943 1.1 junyoung regw(sc, DP_MIX, (MIX_SRC << 16) | MIX_DST);
944 1.1 junyoung
945 1.1 junyoung regw(sc, DP_SRC, FRGD_SRC_FRGD_CLR);
946 1.1 junyoung
947 1.1 junyoung wait_for_fifo(sc, 3);
948 1.1 junyoung regw(sc, CLR_CMP_CLR, 0);
949 1.1 junyoung regw(sc, CLR_CMP_MASK, 0xffffffff);
950 1.1 junyoung regw(sc, CLR_CMP_CNTL, 0);
951 1.1 junyoung
952 1.1 junyoung wait_for_fifo(sc, 2);
953 1.1 junyoung switch (sc->bits_per_pixel) {
954 1.1 junyoung case 8:
955 1.1 junyoung regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP);
956 1.1 junyoung regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP);
957 1.14.2.5 skrll /* XXX Macallan: huh? We /want/ an 8 bit per channel palette! */
958 1.14.2.5 skrll /*regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) & ~DAC_8BIT_EN);*/
959 1.14.2.5 skrll regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
960 1.1 junyoung break;
961 1.1 junyoung #if 0
962 1.1 junyoung case 32:
963 1.1 junyoung regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
964 1.1 junyoung regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
965 1.1 junyoung regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
966 1.1 junyoung break;
967 1.1 junyoung #endif
968 1.1 junyoung }
969 1.1 junyoung
970 1.1 junyoung wait_for_fifo(sc, 5);
971 1.1 junyoung regw(sc, CRTC_INT_CNTL, regr(sc, CRTC_INT_CNTL) & ~0x20);
972 1.1 junyoung regw(sc, GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
973 1.1 junyoung
974 1.1 junyoung wait_for_idle(sc);
975 1.1 junyoung }
976 1.1 junyoung
977 1.1 junyoung void
978 1.1 junyoung mach64_adjust_frame(struct mach64_softc *sc, int x, int y)
979 1.1 junyoung {
980 1.1 junyoung int offset;
981 1.1 junyoung
982 1.1 junyoung offset = ((x + y * sc->virt_x) * (sc->bits_per_pixel >> 3)) >> 3;
983 1.1 junyoung
984 1.1 junyoung regw(sc, CRTC_OFF_PITCH, (regr(sc, CRTC_OFF_PITCH) & 0xfff00000) |
985 1.1 junyoung offset);
986 1.1 junyoung }
987 1.1 junyoung
988 1.1 junyoung void
989 1.1 junyoung mach64_set_dsp(struct mach64_softc *sc)
990 1.1 junyoung {
991 1.1 junyoung u_int32_t fifo_depth, page_size, dsp_precision, dsp_loop_latency;
992 1.1 junyoung u_int32_t dsp_off, dsp_on, dsp_xclks_per_qw;
993 1.1 junyoung u_int32_t xclks_per_qw, y;
994 1.1 junyoung u_int32_t fifo_off, fifo_on;
995 1.1 junyoung
996 1.1 junyoung if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
997 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II ||
998 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIP ||
999 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_PCI ||
1000 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_AGP_B ||
1001 1.1 junyoung mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_AGP_P) {
1002 1.1 junyoung dsp_loop_latency = 0;
1003 1.1 junyoung fifo_depth = 24;
1004 1.1 junyoung } else {
1005 1.1 junyoung dsp_loop_latency = 2;
1006 1.1 junyoung fifo_depth = 32;
1007 1.1 junyoung }
1008 1.1 junyoung
1009 1.1 junyoung dsp_precision = 0;
1010 1.1 junyoung xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) /
1011 1.1 junyoung (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel);
1012 1.1 junyoung y = (xclks_per_qw * fifo_depth) >> 11;
1013 1.1 junyoung while (y) {
1014 1.1 junyoung y >>= 1;
1015 1.1 junyoung dsp_precision++;
1016 1.1 junyoung }
1017 1.1 junyoung dsp_precision -= 5;
1018 1.1 junyoung fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6);
1019 1.1 junyoung
1020 1.1 junyoung switch (sc->memtype) {
1021 1.1 junyoung case DRAM:
1022 1.1 junyoung case EDO_DRAM:
1023 1.1 junyoung case PSEUDO_EDO:
1024 1.1 junyoung if (sc->memsize > 1024) {
1025 1.1 junyoung page_size = 9;
1026 1.1 junyoung dsp_loop_latency += 6;
1027 1.1 junyoung } else {
1028 1.1 junyoung page_size = 10;
1029 1.1 junyoung if (sc->memtype == DRAM)
1030 1.1 junyoung dsp_loop_latency += 8;
1031 1.1 junyoung else
1032 1.1 junyoung dsp_loop_latency += 7;
1033 1.1 junyoung }
1034 1.1 junyoung break;
1035 1.1 junyoung case SDRAM:
1036 1.1 junyoung case SGRAM:
1037 1.1 junyoung if (sc->memsize > 1024) {
1038 1.1 junyoung page_size = 8;
1039 1.1 junyoung dsp_loop_latency += 8;
1040 1.1 junyoung } else {
1041 1.1 junyoung page_size = 10;
1042 1.1 junyoung dsp_loop_latency += 9;
1043 1.1 junyoung }
1044 1.1 junyoung break;
1045 1.1 junyoung default:
1046 1.1 junyoung page_size = 10;
1047 1.1 junyoung dsp_loop_latency += 9;
1048 1.1 junyoung break;
1049 1.1 junyoung }
1050 1.1 junyoung
1051 1.1 junyoung if (xclks_per_qw >= (page_size << 11))
1052 1.1 junyoung fifo_on = ((2 * page_size + 1) << 6) + (xclks_per_qw >> 5);
1053 1.1 junyoung else
1054 1.1 junyoung fifo_on = (3 * page_size + 2) << 6;
1055 1.1 junyoung
1056 1.1 junyoung dsp_xclks_per_qw = xclks_per_qw >> dsp_precision;
1057 1.1 junyoung dsp_on = fifo_on >> dsp_precision;
1058 1.1 junyoung dsp_off = fifo_off >> dsp_precision;
1059 1.1 junyoung
1060 1.1 junyoung #ifdef MACH64_DEBUG
1061 1.1 junyoung printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
1062 1.1 junyoung "dsp_precision = %d, dsp_loop_latency = %d,\n"
1063 1.1 junyoung "mclk_fb_div = %d, vclk_fb_div = %d,\n"
1064 1.1 junyoung "mclk_post_div = %d, vclk_post_div = %d\n",
1065 1.1 junyoung dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency,
1066 1.1 junyoung sc->mclk_fb_div, sc->vclk_fb_div,
1067 1.1 junyoung sc->mclk_post_div, sc->vclk_post_div);
1068 1.1 junyoung #endif
1069 1.1 junyoung
1070 1.1 junyoung regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF));
1071 1.1 junyoung regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) |
1072 1.1 junyoung ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) |
1073 1.1 junyoung (dsp_xclks_per_qw & DSP_XCLKS_PER_QW));
1074 1.1 junyoung }
1075 1.1 junyoung
1076 1.1 junyoung void
1077 1.1 junyoung mach64_set_pll(struct mach64_softc *sc, int clock)
1078 1.1 junyoung {
1079 1.1 junyoung int q;
1080 1.1 junyoung
1081 1.1 junyoung q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
1082 1.1 junyoung #ifdef MACH64_DEBUG
1083 1.1 junyoung printf("q = %d\n", q);
1084 1.1 junyoung #endif
1085 1.1 junyoung if (q > 25500) {
1086 1.1 junyoung printf("Warning: q > 25500\n");
1087 1.1 junyoung q = 25500;
1088 1.1 junyoung sc->vclk_post_div = 1;
1089 1.1 junyoung sc->log2_vclk_post_div = 0;
1090 1.1 junyoung } else if (q > 12750) {
1091 1.1 junyoung sc->vclk_post_div = 1;
1092 1.1 junyoung sc->log2_vclk_post_div = 0;
1093 1.1 junyoung } else if (q > 6350) {
1094 1.1 junyoung sc->vclk_post_div = 2;
1095 1.1 junyoung sc->log2_vclk_post_div = 1;
1096 1.1 junyoung } else if (q > 3150) {
1097 1.1 junyoung sc->vclk_post_div = 4;
1098 1.1 junyoung sc->log2_vclk_post_div = 2;
1099 1.1 junyoung } else if (q >= 1600) {
1100 1.1 junyoung sc->vclk_post_div = 8;
1101 1.1 junyoung sc->log2_vclk_post_div = 3;
1102 1.1 junyoung } else {
1103 1.1 junyoung printf("Warning: q < 1600\n");
1104 1.1 junyoung sc->vclk_post_div = 8;
1105 1.1 junyoung sc->log2_vclk_post_div = 3;
1106 1.1 junyoung }
1107 1.1 junyoung sc->vclk_fb_div = q * sc->vclk_post_div / 100;
1108 1.1 junyoung
1109 1.1 junyoung regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div);
1110 1.1 junyoung regwb_pll(sc, VCLK_POST_DIV, sc->log2_vclk_post_div);
1111 1.1 junyoung regwb_pll(sc, VCLK0_FB_DIV, sc->vclk_fb_div);
1112 1.1 junyoung }
1113 1.1 junyoung
1114 1.1 junyoung void
1115 1.1 junyoung mach64_init_lut(struct mach64_softc *sc)
1116 1.1 junyoung {
1117 1.14.2.5 skrll /* XXX this is pretty dodgy since it's perfectly possible that
1118 1.14.2.5 skrll both terminal emulations are compiled into the kernel, in this
1119 1.14.2.5 skrll case we'd install the VT100 colour map which may be wrong */
1120 1.14.2.5 skrll #ifdef WSEMUL_SUN
1121 1.14.2.5 skrll mach64_putpalreg(sc,0,255,255,255);
1122 1.14.2.5 skrll mach64_putpalreg(sc,1,0,0,0);
1123 1.14.2.5 skrll mach64_putpalreg(sc,255,0,0,0);
1124 1.14.2.5 skrll #endif
1125 1.14.2.5 skrll #ifdef WSEMUL_VT100
1126 1.14.2.5 skrll {
1127 1.14.2.5 skrll int i,idx;
1128 1.14.2.5 skrll idx=0;
1129 1.14.2.5 skrll for(i=0;i<256;i++) {
1130 1.14.2.5 skrll mach64_putpalreg(sc,i,rasops_cmap[idx],rasops_cmap[idx+1],rasops_cmap[idx+2]);
1131 1.14.2.5 skrll idx+=3;
1132 1.14.2.5 skrll }
1133 1.14.2.5 skrll }
1134 1.14.2.5 skrll #endif
1135 1.14.2.5 skrll }
1136 1.1 junyoung
1137 1.14.2.5 skrll int mach64_putpalreg(struct mach64_softc *sc, uint8_t index, uint8_t r, uint8_t g, uint8_t b)
1138 1.14.2.5 skrll {
1139 1.14.2.5 skrll sc->sc_cmap_red[index]=r;
1140 1.14.2.5 skrll sc->sc_cmap_green[index]=g;
1141 1.14.2.5 skrll sc->sc_cmap_blue[index]=b;
1142 1.14.2.5 skrll /* writing the dac index takes a while, in theory we can poll some register
1143 1.14.2.5 skrll to see when it's ready - but we better avoid writing it unnecessarily */
1144 1.14.2.5 skrll if(index!=sc->sc_dacw)
1145 1.14.2.5 skrll {
1146 1.14.2.5 skrll regwb(sc, DAC_MASK, 0xff);
1147 1.14.2.5 skrll regwb(sc, DAC_WINDEX, index);
1148 1.14.2.5 skrll }
1149 1.14.2.5 skrll sc->sc_dacw=index+1;
1150 1.14.2.5 skrll regwb(sc, DAC_DATA, r);
1151 1.14.2.5 skrll regwb(sc, DAC_DATA, g);
1152 1.14.2.5 skrll regwb(sc, DAC_DATA, b);
1153 1.14.2.5 skrll return 0;
1154 1.14.2.5 skrll }
1155 1.1 junyoung
1156 1.14.2.5 skrll int mach64_putcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
1157 1.14.2.5 skrll {
1158 1.14.2.5 skrll u_int index = cm->index;
1159 1.14.2.5 skrll u_int count = cm->count;
1160 1.14.2.5 skrll int i, error;
1161 1.14.2.5 skrll u_char rbuf[256], gbuf[256], bbuf[256];
1162 1.14.2.5 skrll u_char *r, *g, *b;
1163 1.14.2.5 skrll
1164 1.14.2.5 skrll printf("putcmap: %d %d\n",index, count);
1165 1.14.2.5 skrll if (cm->index >= 256 || cm->count > 256 ||
1166 1.14.2.5 skrll (cm->index + cm->count) > 256)
1167 1.14.2.5 skrll return EINVAL;
1168 1.14.2.5 skrll error = copyin(cm->red, &rbuf[index], count);
1169 1.14.2.5 skrll if (error)
1170 1.14.2.5 skrll return error;
1171 1.14.2.5 skrll error = copyin(cm->green, &gbuf[index], count);
1172 1.14.2.5 skrll if (error)
1173 1.14.2.5 skrll return error;
1174 1.14.2.5 skrll error = copyin(cm->blue, &bbuf[index], count);
1175 1.14.2.5 skrll if (error)
1176 1.14.2.5 skrll return error;
1177 1.14.2.5 skrll
1178 1.14.2.5 skrll memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
1179 1.14.2.5 skrll memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
1180 1.14.2.5 skrll memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
1181 1.14.2.5 skrll
1182 1.14.2.5 skrll r = &sc->sc_cmap_red[index];
1183 1.14.2.5 skrll g = &sc->sc_cmap_green[index];
1184 1.14.2.5 skrll b = &sc->sc_cmap_blue[index];
1185 1.14.2.5 skrll
1186 1.14.2.5 skrll for (i = 0; i < count; i++) {
1187 1.14.2.5 skrll mach64_putpalreg(sc,index,*r, *g, *b);
1188 1.14.2.5 skrll index++;
1189 1.14.2.5 skrll r++, g++, b++;
1190 1.1 junyoung }
1191 1.14.2.5 skrll return 0;
1192 1.14.2.5 skrll }
1193 1.14.2.5 skrll
1194 1.14.2.5 skrll int mach64_getcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
1195 1.14.2.5 skrll {
1196 1.14.2.5 skrll u_int index = cm->index;
1197 1.14.2.5 skrll u_int count = cm->count;
1198 1.14.2.5 skrll int error;
1199 1.14.2.5 skrll
1200 1.14.2.5 skrll if (index >= 255 || count > 256 || index + count > 256)
1201 1.14.2.5 skrll return EINVAL;
1202 1.14.2.5 skrll
1203 1.14.2.5 skrll error = copyout(&sc->sc_cmap_red[index], cm->red, count);
1204 1.14.2.5 skrll if (error)
1205 1.14.2.5 skrll return error;
1206 1.14.2.5 skrll error = copyout(&sc->sc_cmap_green[index], cm->green, count);
1207 1.14.2.5 skrll if (error)
1208 1.14.2.5 skrll return error;
1209 1.14.2.5 skrll error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
1210 1.14.2.5 skrll if (error)
1211 1.14.2.5 skrll return error;
1212 1.14.2.5 skrll
1213 1.14.2.5 skrll return 0;
1214 1.1 junyoung }
1215 1.1 junyoung
1216 1.1 junyoung void
1217 1.1 junyoung mach64_switch_screen(struct mach64_softc *sc)
1218 1.1 junyoung {
1219 1.1 junyoung struct mach64screen *scr, *oldscr;
1220 1.1 junyoung const struct wsscreen_descr *type;
1221 1.1 junyoung
1222 1.1 junyoung scr = sc->wanted;
1223 1.1 junyoung if (!scr) {
1224 1.1 junyoung printf("mach64_switch_screen: disappeared\n");
1225 1.1 junyoung (*sc->switchcb)(sc->switchcbarg, EIO, 0);
1226 1.1 junyoung return;
1227 1.1 junyoung }
1228 1.1 junyoung type = scr->type;
1229 1.1 junyoung oldscr = sc->active; /* can be NULL! */
1230 1.1 junyoung #ifdef DIAGNOSTIC
1231 1.1 junyoung if (oldscr) {
1232 1.1 junyoung if (!oldscr->active)
1233 1.1 junyoung panic("mach64_switch_screen: not active");
1234 1.11 martin if (oldscr->type != sc->currenttype)
1235 1.1 junyoung panic("mach64_switch_screen: bad type");
1236 1.1 junyoung }
1237 1.1 junyoung #endif
1238 1.1 junyoung if (scr == oldscr)
1239 1.1 junyoung return;
1240 1.1 junyoung
1241 1.1 junyoung #ifdef DIAGNOSTIC
1242 1.14.2.5 skrll /* XXX Macallan: this one bites us at reboot */
1243 1.14.2.5 skrll /* if (scr->active)
1244 1.14.2.5 skrll panic("mach64_switch_screen: active");*/
1245 1.1 junyoung #endif
1246 1.1 junyoung
1247 1.1 junyoung if (oldscr)
1248 1.1 junyoung oldscr->active = 0;
1249 1.1 junyoung
1250 1.1 junyoung if (sc->currenttype != type) {
1251 1.1 junyoung mach64_set_screentype(sc, type);
1252 1.1 junyoung sc->currenttype = type;
1253 1.1 junyoung }
1254 1.1 junyoung
1255 1.1 junyoung scr->dispoffset = scr->mindispoffset;
1256 1.1 junyoung
1257 1.1 junyoung if (!oldscr || (scr->dispoffset != oldscr->dispoffset)) {
1258 1.1 junyoung
1259 1.1 junyoung }
1260 1.1 junyoung
1261 1.1 junyoung /* Clear the entire screen. */
1262 1.1 junyoung
1263 1.1 junyoung scr->active = 1;
1264 1.1 junyoung mach64_restore_screen(scr, type, scr->mem);
1265 1.1 junyoung
1266 1.1 junyoung sc->active = scr;
1267 1.1 junyoung
1268 1.1 junyoung mach64_cursor(scr, scr->cursoron, scr->cursorrow, scr->cursorcol);
1269 1.1 junyoung
1270 1.1 junyoung sc->wanted = 0;
1271 1.1 junyoung if (sc->switchcb)
1272 1.1 junyoung (*sc->switchcb)(sc->switchcbarg, 0, 0);
1273 1.1 junyoung }
1274 1.1 junyoung
1275 1.1 junyoung void
1276 1.1 junyoung mach64_restore_screen(struct mach64screen *scr,
1277 1.1 junyoung const struct wsscreen_descr *type, u_int16_t *mem)
1278 1.1 junyoung {
1279 1.1 junyoung
1280 1.1 junyoung }
1281 1.1 junyoung
1282 1.6 junyoung int
1283 1.1 junyoung mach64_set_screentype(struct mach64_softc *sc, const struct wsscreen_descr *des)
1284 1.1 junyoung {
1285 1.6 junyoung struct mach64_crtcregs regs;
1286 1.1 junyoung
1287 1.6 junyoung if (mach64_calc_crtcregs(sc, ®s,
1288 1.6 junyoung (struct videomode *)des->modecookie))
1289 1.6 junyoung return 1;
1290 1.6 junyoung
1291 1.6 junyoung mach64_set_crtcregs(sc, ®s);
1292 1.6 junyoung return 0;
1293 1.1 junyoung }
1294 1.1 junyoung
1295 1.5 junyoung int
1296 1.5 junyoung mach64_is_console(struct pci_attach_args *pa)
1297 1.5 junyoung {
1298 1.5 junyoung #ifdef __sparc__
1299 1.5 junyoung int node;
1300 1.5 junyoung
1301 1.5 junyoung node = PCITAG_NODE(pa->pa_tag);
1302 1.5 junyoung if (node == -1)
1303 1.5 junyoung return 0;
1304 1.5 junyoung
1305 1.14.2.2 skrll return (node == prom_instance_to_package(prom_stdout()));
1306 1.5 junyoung #else
1307 1.5 junyoung return 1;
1308 1.5 junyoung #endif
1309 1.5 junyoung }
1310 1.5 junyoung
1311 1.1 junyoung /*
1312 1.1 junyoung * wsdisplay_emulops
1313 1.1 junyoung */
1314 1.1 junyoung
1315 1.1 junyoung void
1316 1.1 junyoung mach64_cursor(void *cookie, int on, int row, int col)
1317 1.1 junyoung {
1318 1.1 junyoung
1319 1.1 junyoung }
1320 1.1 junyoung
1321 1.7 martin #if 0
1322 1.1 junyoung int
1323 1.1 junyoung mach64_mapchar(void *cookie, int uni, u_int *index)
1324 1.1 junyoung {
1325 1.1 junyoung
1326 1.1 junyoung return 0;
1327 1.1 junyoung }
1328 1.1 junyoung
1329 1.1 junyoung void
1330 1.1 junyoung mach64_putchar(void *cookie, int row, int col, u_int c, long attr)
1331 1.1 junyoung {
1332 1.1 junyoung
1333 1.1 junyoung }
1334 1.14.2.5 skrll #endif
1335 1.1 junyoung
1336 1.1 junyoung void
1337 1.1 junyoung mach64_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
1338 1.1 junyoung {
1339 1.14.2.5 skrll struct rasops_info *ri=cookie;
1340 1.14.2.5 skrll struct mach64_softc *sc=ri->ri_hw;
1341 1.14.2.5 skrll int32_t xs,xd,y,width,height;
1342 1.14.2.5 skrll
1343 1.14.2.5 skrll xs=ri->ri_xorigin+ri->ri_font->fontwidth*srccol;
1344 1.14.2.5 skrll xd=ri->ri_xorigin+ri->ri_font->fontwidth*dstcol;
1345 1.14.2.5 skrll y=ri->ri_yorigin+ri->ri_font->fontheight*row;
1346 1.14.2.5 skrll width=ri->ri_font->fontwidth*ncols;
1347 1.14.2.5 skrll height=ri->ri_font->fontheight;
1348 1.14.2.5 skrll mach64_bitblt(sc,xs,y,xd,y,width,height,MIX_SRC,0xff);
1349 1.1 junyoung }
1350 1.1 junyoung
1351 1.1 junyoung void
1352 1.1 junyoung mach64_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
1353 1.1 junyoung {
1354 1.14.2.5 skrll struct rasops_info *ri=cookie;
1355 1.14.2.5 skrll struct mach64_softc *sc=ri->ri_hw;
1356 1.14.2.5 skrll int32_t x,y,width,height,fg,bg,ul;;
1357 1.14.2.5 skrll
1358 1.14.2.5 skrll x=ri->ri_xorigin+ri->ri_font->fontwidth*startcol;
1359 1.14.2.5 skrll y=ri->ri_yorigin+ri->ri_font->fontheight*row;
1360 1.14.2.5 skrll width=ri->ri_font->fontwidth*ncols;
1361 1.14.2.5 skrll height=ri->ri_font->fontheight;
1362 1.14.2.5 skrll rasops_unpack_attr(fillattr,&fg,&bg,&ul);
1363 1.14.2.5 skrll
1364 1.14.2.5 skrll mach64_rectfill(sc,x,y,width,height,bg);
1365 1.1 junyoung
1366 1.1 junyoung }
1367 1.1 junyoung
1368 1.1 junyoung void
1369 1.1 junyoung mach64_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
1370 1.1 junyoung {
1371 1.14.2.5 skrll struct rasops_info *ri=cookie;
1372 1.14.2.5 skrll struct mach64_softc *sc=ri->ri_hw;
1373 1.14.2.5 skrll int32_t x,ys,yd,width,height;
1374 1.14.2.5 skrll
1375 1.14.2.5 skrll x=ri->ri_xorigin;
1376 1.14.2.5 skrll ys=ri->ri_yorigin+ri->ri_font->fontheight*srcrow;
1377 1.14.2.5 skrll yd=ri->ri_yorigin+ri->ri_font->fontheight*dstrow;
1378 1.14.2.5 skrll width=ri->ri_emuwidth;
1379 1.14.2.5 skrll height=ri->ri_font->fontheight*nrows;
1380 1.14.2.5 skrll mach64_bitblt(sc,x,ys,x,yd,width,height,MIX_SRC,0xff);
1381 1.14.2.5 skrll }
1382 1.14.2.5 skrll
1383 1.14.2.5 skrll void mach64_bitblt(struct mach64_softc *sc, int xs, int ys, int xd, int yd, int width, int height, int rop,
1384 1.14.2.5 skrll int mask)
1385 1.14.2.5 skrll {
1386 1.14.2.5 skrll uint32_t dest_ctl=0;
1387 1.14.2.5 skrll wait_for_idle(sc);
1388 1.14.2.5 skrll regw(sc,DP_WRITE_MASK,mask); /* XXX only good for 8 bit */
1389 1.14.2.5 skrll regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_8BPP|HOST_8BPP);
1390 1.14.2.5 skrll regw(sc,DP_SRC,FRGD_SRC_BLIT);
1391 1.14.2.5 skrll regw(sc,DP_MIX,(rop&0xffff)<<16);
1392 1.14.2.5 skrll regw(sc,CLR_CMP_CNTL,0); /* no transparency */
1393 1.14.2.5 skrll if(yd<ys) {
1394 1.14.2.5 skrll dest_ctl=DST_Y_TOP_TO_BOTTOM;
1395 1.14.2.5 skrll } else {
1396 1.14.2.5 skrll ys+=height-1;
1397 1.14.2.5 skrll yd+=height-1;
1398 1.14.2.5 skrll dest_ctl=DST_Y_BOTTOM_TO_TOP;
1399 1.14.2.5 skrll }
1400 1.14.2.5 skrll if(xd<xs) {
1401 1.14.2.5 skrll dest_ctl|=DST_X_LEFT_TO_RIGHT;
1402 1.14.2.5 skrll regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
1403 1.14.2.5 skrll } else {
1404 1.14.2.5 skrll dest_ctl|=DST_X_RIGHT_TO_LEFT;
1405 1.14.2.5 skrll xs+=width-1;
1406 1.14.2.5 skrll xd+=width-1;
1407 1.14.2.5 skrll regw(sc,SRC_CNTL,SRC_LINE_X_RIGHT_TO_LEFT);
1408 1.14.2.5 skrll }
1409 1.14.2.5 skrll regw(sc,DST_CNTL,dest_ctl);
1410 1.14.2.5 skrll
1411 1.14.2.5 skrll regw(sc,SRC_Y_X,(xs<<16)|ys);
1412 1.14.2.5 skrll regw(sc,SRC_WIDTH1,width);
1413 1.14.2.5 skrll regw(sc,DST_Y_X,(xd<<16)|yd);
1414 1.14.2.5 skrll regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
1415 1.14.2.5 skrll /* as long as the other rasops* functions aren't aware of the blitter we must wait here
1416 1.14.2.5 skrll or the blitter might not be done when someone else draws the next line */
1417 1.14.2.5 skrll wait_for_idle(sc);
1418 1.14.2.5 skrll }
1419 1.14.2.5 skrll
1420 1.14.2.5 skrll void mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int height, int colour)
1421 1.14.2.5 skrll {
1422 1.14.2.5 skrll wait_for_idle(sc);
1423 1.14.2.5 skrll regw(sc,DP_WRITE_MASK,0xff);
1424 1.14.2.5 skrll regw(sc,DP_FRGD_CLR,colour);
1425 1.14.2.5 skrll regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_8BPP|HOST_8BPP);
1426 1.14.2.5 skrll regw(sc,DP_SRC,FRGD_SRC_FRGD_CLR);
1427 1.14.2.5 skrll regw(sc,DP_MIX,(MIX_SRC)<<16);
1428 1.14.2.5 skrll regw(sc,CLR_CMP_CNTL,0); /* no transparency */
1429 1.14.2.5 skrll regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
1430 1.14.2.5 skrll regw(sc,DST_CNTL,DST_X_LEFT_TO_RIGHT|DST_Y_TOP_TO_BOTTOM);
1431 1.14.2.5 skrll
1432 1.14.2.5 skrll regw(sc,SRC_Y_X,(x<<16)|y);
1433 1.14.2.5 skrll regw(sc,SRC_WIDTH1,width);
1434 1.14.2.5 skrll regw(sc,DST_Y_X,(x<<16)|y);
1435 1.14.2.5 skrll regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
1436 1.14.2.5 skrll wait_for_idle(sc);
1437 1.1 junyoung }
1438 1.1 junyoung
1439 1.14.2.5 skrll void mach64_showpal(struct mach64_softc *sc)
1440 1.14.2.5 skrll {
1441 1.14.2.5 skrll int i,x=0;
1442 1.14.2.5 skrll for (i=0;i<16;i++) {
1443 1.14.2.5 skrll mach64_rectfill(sc,x,0,64,64,i);
1444 1.14.2.5 skrll x+=64;
1445 1.14.2.5 skrll }
1446 1.14.2.5 skrll }
1447 1.14.2.5 skrll
1448 1.7 martin int
1449 1.7 martin mach64_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
1450 1.1 junyoung {
1451 1.1 junyoung
1452 1.7 martin return 0;
1453 1.1 junyoung }
1454 1.1 junyoung
1455 1.7 martin void
1456 1.7 martin mach64_eraserows(void *cookie, int row, int nrows, long fillattr)
1457 1.1 junyoung {
1458 1.14.2.5 skrll struct rasops_info *ri=cookie;
1459 1.14.2.5 skrll struct mach64_softc *sc=ri->ri_hw;
1460 1.14.2.5 skrll int32_t x,y,width,height,fg,bg,ul;
1461 1.14.2.5 skrll
1462 1.14.2.5 skrll x=ri->ri_xorigin;
1463 1.14.2.5 skrll y=ri->ri_yorigin+ri->ri_font->fontheight*row;
1464 1.14.2.5 skrll width=ri->ri_emuwidth;
1465 1.14.2.5 skrll height=ri->ri_font->fontheight*nrows;
1466 1.14.2.5 skrll rasops_unpack_attr(fillattr,&fg,&bg,&ul);
1467 1.14.2.5 skrll
1468 1.14.2.5 skrll mach64_rectfill(sc,x,y,width,height,bg);
1469 1.1 junyoung }
1470 1.1 junyoung
1471 1.1 junyoung /*
1472 1.1 junyoung * wsdisplay_accessops
1473 1.1 junyoung */
1474 1.1 junyoung
1475 1.1 junyoung int
1476 1.14.2.4 skrll mach64_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct lwp *l)
1477 1.1 junyoung {
1478 1.14.2.5 skrll /* we'll probably need to add more stuff here */
1479 1.14.2.5 skrll struct mach64_softc *sc = v;
1480 1.14.2.5 skrll struct wsdisplay_fbinfo *wdf;
1481 1.14.2.5 skrll struct mach64screen *ms=sc->active;
1482 1.14.2.5 skrll switch (cmd) {
1483 1.14.2.5 skrll case WSDISPLAYIO_GTYPE:
1484 1.14.2.5 skrll *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; /* XXX ? */
1485 1.14.2.5 skrll return 0;
1486 1.14.2.5 skrll
1487 1.14.2.5 skrll case WSDISPLAYIO_GINFO:
1488 1.14.2.5 skrll wdf = (void *)data;
1489 1.14.2.5 skrll wdf->height = ms->ri.ri_height;
1490 1.14.2.5 skrll wdf->width = ms->ri.ri_width;
1491 1.14.2.5 skrll wdf->depth = ms->ri.ri_depth;
1492 1.14.2.5 skrll wdf->cmsize = 256;
1493 1.14.2.5 skrll return 0;
1494 1.14.2.5 skrll case WSDISPLAYIO_GETCMAP:
1495 1.14.2.5 skrll return mach64_getcmap(sc, (struct wsdisplay_cmap *)data);
1496 1.14.2.5 skrll
1497 1.14.2.5 skrll case WSDISPLAYIO_PUTCMAP:
1498 1.14.2.5 skrll return mach64_putcmap(sc, (struct wsdisplay_cmap *)data);
1499 1.14.2.5 skrll /* PCI config read/write passthrough. */
1500 1.14.2.5 skrll case PCI_IOC_CFGREAD:
1501 1.14.2.5 skrll case PCI_IOC_CFGWRITE:
1502 1.14.2.5 skrll return (pci_devioctl(sc->sc_pc, sc->sc_pcitag,
1503 1.14.2.5 skrll cmd, data, flag, p));
1504 1.14.2.5 skrll #ifdef notyet
1505 1.14.2.5 skrll case WSDISPLAYIO_SMODE:
1506 1.14.2.5 skrll {
1507 1.14.2.5 skrll int new_mode=*(int*)data;
1508 1.14.2.5 skrll if(new_mode!=sc->sc_mode)
1509 1.14.2.5 skrll {
1510 1.14.2.5 skrll sc->sc_mode=new_mode;
1511 1.14.2.5 skrll if(new_mode==WSDISPLAYIO_MODE_EMUL)
1512 1.14.2.5 skrll {
1513 1.14.2.5 skrll /* we'll probably want to reset the console into a known state here
1514 1.14.2.5 skrll just in case the Xserver crashed or didn't properly clean up after
1515 1.14.2.5 skrll itself for whetever reason */
1516 1.14.2.5 skrll }
1517 1.14.2.5 skrll }
1518 1.14.2.5 skrll }
1519 1.14.2.5 skrll #endif
1520 1.14.2.5 skrll }
1521 1.14.2.5 skrll return EPASSTHROUGH;
1522 1.1 junyoung }
1523 1.1 junyoung
1524 1.1 junyoung paddr_t
1525 1.1 junyoung mach64_mmap(void *v, off_t offset, int prot)
1526 1.1 junyoung {
1527 1.14.2.5 skrll struct mach64_softc *sc = v;
1528 1.14.2.5 skrll paddr_t pa;
1529 1.14.2.5 skrll /* 'regular' framebuffer mmap()ing */
1530 1.14.2.5 skrll if(offset<sc->sc_apersize) {
1531 1.14.2.5 skrll pa = bus_space_mmap(sc->sc_memt,sc->sc_aperbase+offset,0,prot,BUS_SPACE_MAP_LINEAR);
1532 1.14.2.5 skrll return pa;
1533 1.14.2.5 skrll }
1534 1.14.2.5 skrll /* allow XFree86 to mmap() PCI space as if the BARs contain physical addresses */
1535 1.14.2.5 skrll if((offset>0x80000000) && (offset<=0xffffffff)) {
1536 1.14.2.5 skrll pa = bus_space_mmap(sc->sc_memt,offset,0,prot,BUS_SPACE_MAP_LINEAR);
1537 1.14.2.5 skrll return pa;
1538 1.14.2.5 skrll }
1539 1.1 junyoung return -1;
1540 1.1 junyoung }
1541 1.1 junyoung
1542 1.1 junyoung int
1543 1.1 junyoung mach64_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
1544 1.1 junyoung int *curxp, int *curyp, long *defattrp)
1545 1.1 junyoung {
1546 1.1 junyoung struct mach64_softc *sc = v;
1547 1.1 junyoung struct mach64screen *scr;
1548 1.1 junyoung
1549 1.7 martin scr = malloc(sizeof(struct mach64screen), M_DEVBUF, M_WAITOK|M_ZERO);
1550 1.7 martin mach64_init_screen(sc, scr, type, 0, defattrp, sc->active == NULL);
1551 1.7 martin rasops_init(&scr->ri, mach64_console_screen.ri.ri_height / 16,
1552 1.7 martin mach64_console_screen.ri.ri_width / 8);
1553 1.7 martin
1554 1.7 martin scr->mem = malloc(type->ncols * type->nrows * 2, M_DEVBUF,
1555 1.7 martin M_WAITOK);
1556 1.7 martin mach64_eraserows(sc, 0, type->nrows, *defattrp);
1557 1.7 martin if (sc->active == NULL) {
1558 1.1 junyoung scr->active = 1;
1559 1.1 junyoung sc->active = scr;
1560 1.1 junyoung sc->currenttype = type;
1561 1.1 junyoung }
1562 1.1 junyoung
1563 1.1 junyoung *cookiep = scr;
1564 1.1 junyoung *curxp = scr->cursorcol;
1565 1.1 junyoung *curyp = scr->cursorrow;
1566 1.1 junyoung
1567 1.1 junyoung return 0;
1568 1.1 junyoung }
1569 1.1 junyoung
1570 1.1 junyoung void
1571 1.1 junyoung mach64_free_screen(void *v, void *cookie)
1572 1.1 junyoung {
1573 1.1 junyoung struct mach64_softc *sc = v;
1574 1.1 junyoung struct mach64screen *scr = cookie;
1575 1.1 junyoung
1576 1.1 junyoung LIST_REMOVE(scr, next);
1577 1.1 junyoung if (scr != &mach64_console_screen)
1578 1.1 junyoung free(scr, M_DEVBUF);
1579 1.1 junyoung else
1580 1.1 junyoung panic("mach64_free_screen: console");
1581 1.1 junyoung
1582 1.1 junyoung if (sc->active == scr)
1583 1.1 junyoung sc->active = 0;
1584 1.1 junyoung }
1585 1.1 junyoung
1586 1.1 junyoung int
1587 1.1 junyoung mach64_show_screen(void *v, void *cookie, int waitok,
1588 1.1 junyoung void (*cb)(void *, int, int), void *cbarg)
1589 1.1 junyoung {
1590 1.1 junyoung struct mach64_softc *sc = v;
1591 1.1 junyoung struct mach64screen *scr, *oldscr;
1592 1.1 junyoung
1593 1.1 junyoung scr = cookie;
1594 1.1 junyoung oldscr = sc->active;
1595 1.1 junyoung if (scr == oldscr)
1596 1.1 junyoung return 0;
1597 1.1 junyoung
1598 1.1 junyoung sc->wanted = scr;
1599 1.1 junyoung sc->switchcb = cb;
1600 1.1 junyoung sc->switchcbarg = cbarg;
1601 1.1 junyoung if (cb) {
1602 1.1 junyoung callout_reset(&sc->switch_callout, 0,
1603 1.1 junyoung (void(*)(void *))mach64_switch_screen, sc);
1604 1.1 junyoung return EAGAIN;
1605 1.1 junyoung }
1606 1.1 junyoung
1607 1.1 junyoung mach64_switch_screen(sc);
1608 1.1 junyoung
1609 1.1 junyoung return 0;
1610 1.1 junyoung }
1611 1.1 junyoung
1612 1.7 martin #if 0
1613 1.1 junyoung int
1614 1.1 junyoung mach64_load_font(void *v, void *cookie, struct wsdisplay_font *data)
1615 1.1 junyoung {
1616 1.1 junyoung
1617 1.1 junyoung return 0;
1618 1.1 junyoung }
1619 1.7 martin #endif
1620