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