summitfb.c revision 1.34.4.2 1 1.34.4.2 perseant /* $NetBSD: summitfb.c,v 1.34.4.2 2025/08/02 05:55:42 perseant Exp $ */
2 1.34.4.2 perseant
3 1.34.4.2 perseant /* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */
4 1.34.4.2 perseant
5 1.34.4.2 perseant /*
6 1.34.4.2 perseant * Copyright (c) 2006, 2007 Miodrag Vallat.
7 1.34.4.2 perseant ^ 2024 Michael Lorenz
8 1.34.4.2 perseant *
9 1.34.4.2 perseant * Permission to use, copy, modify, and distribute this software for any
10 1.34.4.2 perseant * purpose with or without fee is hereby granted, provided that the above
11 1.34.4.2 perseant * copyright notice, this permission notice, and the disclaimer below
12 1.34.4.2 perseant * appear in all copies.
13 1.34.4.2 perseant *
14 1.34.4.2 perseant * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 1.34.4.2 perseant * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 1.34.4.2 perseant * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 1.34.4.2 perseant * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 1.34.4.2 perseant * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 1.34.4.2 perseant * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 1.34.4.2 perseant * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 1.34.4.2 perseant */
22 1.34.4.2 perseant
23 1.34.4.2 perseant /*
24 1.34.4.2 perseant * a native driver for HP Visualize FX graphics cards, so far tested only on
25 1.34.4.2 perseant * my FX4
26 1.34.4.2 perseant * STI portions are from Miodrag Vallat's sti_pci.c
27 1.34.4.2 perseant */
28 1.34.4.2 perseant
29 1.34.4.2 perseant #include <sys/cdefs.h>
30 1.34.4.2 perseant __KERNEL_RCSID(0, "$NetBSD: summitfb.c,v 1.34.4.2 2025/08/02 05:55:42 perseant Exp $");
31 1.34.4.2 perseant
32 1.34.4.2 perseant #include <sys/param.h>
33 1.34.4.2 perseant #include <sys/systm.h>
34 1.34.4.2 perseant #include <sys/kmem.h>
35 1.34.4.2 perseant #include <sys/device.h>
36 1.34.4.2 perseant #include <sys/mutex.h>
37 1.34.4.2 perseant
38 1.34.4.2 perseant #include <dev/pci/pcivar.h>
39 1.34.4.2 perseant #include <dev/pci/pcireg.h>
40 1.34.4.2 perseant #include <dev/pci/pcidevs.h>
41 1.34.4.2 perseant #include <dev/pci/pciio.h>
42 1.34.4.2 perseant
43 1.34.4.2 perseant #include <dev/wscons/wsdisplayvar.h>
44 1.34.4.2 perseant #include <dev/wscons/wsconsio.h>
45 1.34.4.2 perseant #include <dev/wsfont/wsfont.h>
46 1.34.4.2 perseant #include <dev/rasops/rasops.h>
47 1.34.4.2 perseant #include <dev/wscons/wsdisplay_vconsvar.h>
48 1.34.4.2 perseant #include <dev/pci/wsdisplay_pci.h>
49 1.34.4.2 perseant #include <dev/wscons/wsdisplay_glyphcachevar.h>
50 1.34.4.2 perseant
51 1.34.4.2 perseant #include <dev/ic/stireg.h>
52 1.34.4.2 perseant #include <dev/ic/summitreg.h>
53 1.34.4.2 perseant #include <dev/ic/stivar.h>
54 1.34.4.2 perseant
55 1.34.4.2 perseant #include "opt_summitfb.h"
56 1.34.4.2 perseant
57 1.34.4.2 perseant #ifdef SUMMITFB_DEBUG
58 1.34.4.2 perseant #define DPRINTF(s) printf s
59 1.34.4.2 perseant #else
60 1.34.4.2 perseant #define DPRINTF(s) __nothing
61 1.34.4.2 perseant #endif
62 1.34.4.2 perseant
63 1.34.4.2 perseant int summitfb_match(device_t, cfdata_t, void *);
64 1.34.4.2 perseant void summitfb_attach(device_t, device_t, void *);
65 1.34.4.2 perseant
66 1.34.4.2 perseant struct summitfb_softc {
67 1.34.4.2 perseant device_t sc_dev;
68 1.34.4.2 perseant pci_chipset_tag_t sc_pc;
69 1.34.4.2 perseant pcitag_t sc_tag;
70 1.34.4.2 perseant
71 1.34.4.2 perseant /* stuff we need in order to use the STI ROM */
72 1.34.4.2 perseant struct sti_softc sc_base;
73 1.34.4.2 perseant struct sti_screen sc_scr;
74 1.34.4.2 perseant bus_space_handle_t sc_romh;
75 1.34.4.2 perseant
76 1.34.4.2 perseant int sc_width, sc_height;
77 1.34.4.2 perseant int sc_locked;
78 1.34.4.2 perseant struct vcons_screen sc_console_screen;
79 1.34.4.2 perseant struct wsscreen_descr sc_defaultscreen_descr;
80 1.34.4.2 perseant const struct wsscreen_descr *sc_screens[1];
81 1.34.4.2 perseant struct wsscreen_list sc_screenlist;
82 1.34.4.2 perseant struct vcons_data vd;
83 1.34.4.2 perseant int sc_mode;
84 1.34.4.2 perseant u_char sc_cmap_red[256];
85 1.34.4.2 perseant u_char sc_cmap_green[256];
86 1.34.4.2 perseant u_char sc_cmap_blue[256];
87 1.34.4.2 perseant uint32_t sc_write_mode, sc_read_mode;
88 1.34.4.2 perseant /* cursor stuff */
89 1.34.4.2 perseant int sc_cursor_x, sc_cursor_y;
90 1.34.4.2 perseant int sc_hot_x, sc_hot_y, sc_enabled;
91 1.34.4.2 perseant /* font-in-vram */
92 1.34.4.2 perseant struct wsdisplay_font *sc_font;
93 1.34.4.2 perseant int sc_font_start; /* x of font area */
94 1.34.4.2 perseant int sc_cols; /* chars per line in font area */
95 1.34.4.2 perseant uint32_t sc_palette[16];
96 1.34.4.2 perseant int sc_video_on;
97 1.34.4.2 perseant glyphcache sc_gc;
98 1.34.4.2 perseant };
99 1.34.4.2 perseant
100 1.34.4.2 perseant CFATTACH_DECL_NEW(summitfb, sizeof(struct summitfb_softc),
101 1.34.4.2 perseant summitfb_match, summitfb_attach, NULL, NULL);
102 1.34.4.2 perseant
103 1.34.4.2 perseant int summitfb_readbar(struct sti_softc *, struct pci_attach_args *, u_int,
104 1.34.4.2 perseant int);
105 1.34.4.2 perseant int summitfb_check_rom(struct summitfb_softc *, struct pci_attach_args *);
106 1.34.4.2 perseant void summitfb_enable_rom(struct sti_softc *);
107 1.34.4.2 perseant void summitfb_disable_rom(struct sti_softc *);
108 1.34.4.2 perseant void summitfb_enable_rom_internal(struct summitfb_softc *);
109 1.34.4.2 perseant void summitfb_disable_rom_internal(struct summitfb_softc *);
110 1.34.4.2 perseant
111 1.34.4.2 perseant void summitfb_setup(struct summitfb_softc *);
112 1.34.4.2 perseant
113 1.34.4.2 perseant /* XXX these really need to go into their own header */
114 1.34.4.2 perseant int sti_pci_is_console(struct pci_attach_args *, bus_addr_t *);
115 1.34.4.2 perseant int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t,
116 1.34.4.2 perseant bus_space_handle_t, bus_addr_t *, u_int);
117 1.34.4.2 perseant int sti_screen_setup(struct sti_screen *, int);
118 1.34.4.2 perseant void sti_describe_screen(struct sti_softc *, struct sti_screen *);
119 1.34.4.2 perseant
120 1.34.4.2 perseant #define PCI_ROM_SIZE(mr) \
121 1.34.4.2 perseant (PCI_MAPREG_ROM_ADDR(mr) & -PCI_MAPREG_ROM_ADDR(mr))
122 1.34.4.2 perseant
123 1.34.4.2 perseant /* wsdisplay stuff */
124 1.34.4.2 perseant static int summitfb_ioctl(void *, void *, u_long, void *, int,
125 1.34.4.2 perseant struct lwp *);
126 1.34.4.2 perseant static paddr_t summitfb_mmap(void *, void *, off_t, int);
127 1.34.4.2 perseant static void summitfb_init_screen(void *, struct vcons_screen *, int,
128 1.34.4.2 perseant long *);
129 1.34.4.2 perseant
130 1.34.4.2 perseant static int summitfb_putcmap(struct summitfb_softc *,
131 1.34.4.2 perseant struct wsdisplay_cmap *);
132 1.34.4.2 perseant static int summitfb_getcmap(struct summitfb_softc *,
133 1.34.4.2 perseant struct wsdisplay_cmap *);
134 1.34.4.2 perseant static void summitfb_restore_palette(struct summitfb_softc *);
135 1.34.4.2 perseant static int summitfb_putpalreg(struct summitfb_softc *, uint8_t, uint8_t,
136 1.34.4.2 perseant uint8_t, uint8_t);
137 1.34.4.2 perseant
138 1.34.4.2 perseant static inline void summitfb_setup_fb(struct summitfb_softc *);
139 1.34.4.2 perseant static void summitfb_clearfb(struct summitfb_softc *);
140 1.34.4.2 perseant static void summitfb_rectfill(struct summitfb_softc *, int, int, int, int,
141 1.34.4.2 perseant uint32_t);
142 1.34.4.2 perseant static void summitfb_bitblt(void *, int, int, int, int, int,
143 1.34.4.2 perseant int, int);
144 1.34.4.2 perseant
145 1.34.4.2 perseant static void summitfb_cursor(void *, int, int, int);
146 1.34.4.2 perseant static void summitfb_putchar(void *, int, int, u_int, long);
147 1.34.4.2 perseant static void summitfb_putchar_aa(void *, int, int, u_int, long);
148 1.34.4.2 perseant static void summitfb_copycols(void *, int, int, int, int);
149 1.34.4.2 perseant static void summitfb_erasecols(void *, int, int, int, long);
150 1.34.4.2 perseant static void summitfb_copyrows(void *, int, int, int);
151 1.34.4.2 perseant static void summitfb_eraserows(void *, int, int, long);
152 1.34.4.2 perseant
153 1.34.4.2 perseant static void summitfb_move_cursor(struct summitfb_softc *, int, int);
154 1.34.4.2 perseant static int summitfb_do_cursor(struct summitfb_softc *,
155 1.34.4.2 perseant struct wsdisplay_cursor *);
156 1.34.4.2 perseant
157 1.34.4.2 perseant static void summitfb_set_video(struct summitfb_softc *, int);
158 1.34.4.2 perseant
159 1.34.4.2 perseant static void summitfb_copyfont(struct summitfb_softc *);
160 1.34.4.2 perseant
161 1.34.4.2 perseant struct wsdisplay_accessops summitfb_accessops = {
162 1.34.4.2 perseant .ioctl = summitfb_ioctl,
163 1.34.4.2 perseant .mmap = summitfb_mmap,
164 1.34.4.2 perseant .alloc_screen = NULL,
165 1.34.4.2 perseant .free_screen = NULL,
166 1.34.4.2 perseant .show_screen = NULL,
167 1.34.4.2 perseant .load_font = NULL,
168 1.34.4.2 perseant .pollc = NULL,
169 1.34.4.2 perseant .scroll = NULL,
170 1.34.4.2 perseant };
171 1.34.4.2 perseant
172 1.34.4.2 perseant static inline void summitfb_wait_fifo(struct summitfb_softc *, uint32_t);
173 1.34.4.2 perseant static inline void summitfb_wait(struct summitfb_softc *);
174 1.34.4.2 perseant
175 1.34.4.2 perseant int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, uint32_t,
176 1.34.4.2 perseant u_int);
177 1.34.4.2 perseant
178 1.34.4.2 perseant int
179 1.34.4.2 perseant summitfb_match(device_t parent, cfdata_t cf, void *aux)
180 1.34.4.2 perseant {
181 1.34.4.2 perseant struct pci_attach_args *paa = aux;
182 1.34.4.2 perseant
183 1.34.4.2 perseant if (PCI_VENDOR(paa->pa_id) != PCI_VENDOR_HP)
184 1.34.4.2 perseant return 0;
185 1.34.4.2 perseant
186 1.34.4.2 perseant if (PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX4)
187 1.34.4.2 perseant return 10; /* beat out sti at pci */
188 1.34.4.2 perseant
189 1.34.4.2 perseant return 0;
190 1.34.4.2 perseant }
191 1.34.4.2 perseant
192 1.34.4.2 perseant static inline uint32_t
193 1.34.4.2 perseant summitfb_read4(struct summitfb_softc *sc, uint32_t offset)
194 1.34.4.2 perseant {
195 1.34.4.2 perseant struct sti_rom *rom = sc->sc_base.sc_rom;
196 1.34.4.2 perseant bus_space_tag_t memt = rom->memt;
197 1.34.4.2 perseant bus_space_handle_t memh = rom->regh[2];
198 1.34.4.2 perseant
199 1.34.4.2 perseant return bus_space_read_stream_4(memt, memh, offset - 0x400000);
200 1.34.4.2 perseant }
201 1.34.4.2 perseant
202 1.34.4.2 perseant static inline void
203 1.34.4.2 perseant summitfb_write4(struct summitfb_softc *sc, uint32_t offset, uint32_t val)
204 1.34.4.2 perseant {
205 1.34.4.2 perseant struct sti_rom *rom = sc->sc_base.sc_rom;
206 1.34.4.2 perseant bus_space_tag_t memt = rom->memt;
207 1.34.4.2 perseant bus_space_handle_t memh = rom->regh[2];
208 1.34.4.2 perseant
209 1.34.4.2 perseant bus_space_write_stream_4(memt, memh, offset - 0x400000, val);
210 1.34.4.2 perseant }
211 1.34.4.2 perseant
212 1.34.4.2 perseant static inline void
213 1.34.4.2 perseant summitfb_write_mode(struct summitfb_softc *sc, uint32_t mode)
214 1.34.4.2 perseant {
215 1.34.4.2 perseant if (sc->sc_write_mode == mode)
216 1.34.4.2 perseant return;
217 1.34.4.2 perseant summitfb_wait(sc);
218 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_WRITE_MODE, mode);
219 1.34.4.2 perseant sc->sc_write_mode = mode;
220 1.34.4.2 perseant }
221 1.34.4.2 perseant
222 1.34.4.2 perseant static inline void
223 1.34.4.2 perseant summitfb_read_mode(struct summitfb_softc *sc, uint32_t mode)
224 1.34.4.2 perseant {
225 1.34.4.2 perseant if (sc->sc_read_mode == mode)
226 1.34.4.2 perseant return;
227 1.34.4.2 perseant summitfb_wait(sc);
228 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_READ_MODE, mode);
229 1.34.4.2 perseant sc->sc_read_mode = mode;
230 1.34.4.2 perseant }
231 1.34.4.2 perseant
232 1.34.4.2 perseant void
233 1.34.4.2 perseant summitfb_attach(device_t parent, device_t self, void *aux)
234 1.34.4.2 perseant {
235 1.34.4.2 perseant struct summitfb_softc *sc = device_private(self);
236 1.34.4.2 perseant struct pci_attach_args *paa = aux;
237 1.34.4.2 perseant struct sti_rom *rom;
238 1.34.4.2 perseant struct rasops_info *ri;
239 1.34.4.2 perseant struct wsemuldisplaydev_attach_args aa;
240 1.34.4.2 perseant struct sti_dd *dd;
241 1.34.4.2 perseant unsigned long defattr = 0;
242 1.34.4.2 perseant int ret, is_console = 0;
243 1.34.4.2 perseant
244 1.34.4.2 perseant sc->sc_dev = self;
245 1.34.4.2 perseant
246 1.34.4.2 perseant sc->sc_pc = paa->pa_pc;
247 1.34.4.2 perseant sc->sc_tag = paa->pa_tag;
248 1.34.4.2 perseant sc->sc_base.sc_dev = self;
249 1.34.4.2 perseant sc->sc_base.sc_enable_rom = summitfb_enable_rom;
250 1.34.4.2 perseant sc->sc_base.sc_disable_rom = summitfb_disable_rom;
251 1.34.4.2 perseant
252 1.34.4.2 perseant aprint_normal("\n");
253 1.34.4.2 perseant
254 1.34.4.2 perseant if (summitfb_check_rom(sc, paa) != 0)
255 1.34.4.2 perseant return;
256 1.34.4.2 perseant
257 1.34.4.2 perseant ret = sti_pci_is_console(paa, sc->sc_base. bases);
258 1.34.4.2 perseant if (ret != 0) {
259 1.34.4.2 perseant sc->sc_base.sc_flags |= STI_CONSOLE;
260 1.34.4.2 perseant is_console = 1;
261 1.34.4.2 perseant }
262 1.34.4.2 perseant rom = kmem_zalloc(sizeof(*rom), KM_SLEEP);
263 1.34.4.2 perseant rom->rom_softc = &sc->sc_base;
264 1.34.4.2 perseant ret = sti_rom_setup(rom, paa->pa_iot, paa->pa_memt, sc->sc_romh,
265 1.34.4.2 perseant sc->sc_base.bases, STI_CODEBASE_MAIN);
266 1.34.4.2 perseant if (ret != 0) {
267 1.34.4.2 perseant kmem_free(rom, sizeof(*rom));
268 1.34.4.2 perseant return;
269 1.34.4.2 perseant }
270 1.34.4.2 perseant
271 1.34.4.2 perseant sc->sc_base.sc_rom = rom;
272 1.34.4.2 perseant dd = &rom->rom_dd;
273 1.34.4.2 perseant
274 1.34.4.2 perseant sc->sc_scr.scr_rom = sc->sc_base.sc_rom;
275 1.34.4.2 perseant ret = sti_screen_setup(&sc->sc_scr, STI_FBMODE);
276 1.34.4.2 perseant
277 1.34.4.2 perseant sti_fetchfonts(&sc->sc_scr, NULL, dd->dd_fntaddr, 0);
278 1.34.4.2 perseant wsfont_init();
279 1.34.4.2 perseant summitfb_copyfont(sc);
280 1.34.4.2 perseant
281 1.34.4.2 perseant sc->sc_width = sc->sc_scr.scr_cfg.scr_width;
282 1.34.4.2 perseant sc->sc_height = sc->sc_scr.scr_cfg.scr_height;
283 1.34.4.2 perseant sc->sc_write_mode = 0xffffffff;
284 1.34.4.2 perseant sc->sc_read_mode = 0xffffffff;
285 1.34.4.2 perseant
286 1.34.4.2 perseant #ifdef SUMMITFB_DEBUG
287 1.34.4.2 perseant sc->sc_height -= 200;
288 1.34.4.2 perseant #endif
289 1.34.4.2 perseant
290 1.34.4.2 perseant sc->sc_defaultscreen_descr = (struct wsscreen_descr){
291 1.34.4.2 perseant .name = "default",
292 1.34.4.2 perseant .ncols = 0, .nrows = 0,
293 1.34.4.2 perseant .textops = NULL,
294 1.34.4.2 perseant .fontwidth = 8, .fontheight = 16,
295 1.34.4.2 perseant .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT |
296 1.34.4.2 perseant WSSCREEN_UNDERLINE | WSSCREEN_RESIZE,
297 1.34.4.2 perseant .modecookie = NULL,
298 1.34.4.2 perseant };
299 1.34.4.2 perseant
300 1.34.4.2 perseant sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
301 1.34.4.2 perseant sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
302 1.34.4.2 perseant sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
303 1.34.4.2 perseant sc->sc_locked = 0;
304 1.34.4.2 perseant
305 1.34.4.2 perseant vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
306 1.34.4.2 perseant &summitfb_accessops);
307 1.34.4.2 perseant sc->vd.init_screen = summitfb_init_screen;
308 1.34.4.2 perseant sc->vd.show_screen_cookie = &sc->sc_gc;
309 1.34.4.2 perseant sc->vd.show_screen_cb = glyphcache_adapt;
310 1.34.4.2 perseant ri = &sc->sc_console_screen.scr_ri;
311 1.34.4.2 perseant
312 1.34.4.2 perseant sc->sc_gc.gc_bitblt = summitfb_bitblt;
313 1.34.4.2 perseant sc->sc_gc.gc_blitcookie = sc;
314 1.34.4.2 perseant sc->sc_gc.gc_rop = RopSrc;
315 1.34.4.2 perseant
316 1.34.4.2 perseant summitfb_setup(sc);
317 1.34.4.2 perseant
318 1.34.4.2 perseant vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr);
319 1.34.4.2 perseant sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
320 1.34.4.2 perseant
321 1.34.4.2 perseant sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
322 1.34.4.2 perseant sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
323 1.34.4.2 perseant sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
324 1.34.4.2 perseant sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
325 1.34.4.2 perseant
326 1.34.4.2 perseant /*
327 1.34.4.2 perseant * STI lies to us - it reports a 2048x2048 framebuffer but blitter
328 1.34.4.2 perseant * ops wrap around below 1024 and we seem to have only about 250
329 1.34.4.2 perseant * usable columns to the right. Should still be enough to cache
330 1.34.4.2 perseant * a font or four.
331 1.34.4.2 perseant * So, the framebuffer seems to be 1536x1024, which is odd since the
332 1.34.4.2 perseant * FX4 is supposed to support resolutions higher than 1280x1024.
333 1.34.4.2 perseant * I guess video memory is allocated in 512x512 chunks
334 1.34.4.2 perseant */
335 1.34.4.2 perseant glyphcache_init(&sc->sc_gc,
336 1.34.4.2 perseant sc->sc_height,
337 1.34.4.2 perseant sc->sc_height,
338 1.34.4.2 perseant (sc->sc_width + 511) & (~511),
339 1.34.4.2 perseant ri->ri_font->fontwidth,
340 1.34.4.2 perseant ri->ri_font->fontheight,
341 1.34.4.2 perseant defattr);
342 1.34.4.2 perseant
343 1.34.4.2 perseant summitfb_restore_palette(sc);
344 1.34.4.2 perseant summitfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height,
345 1.34.4.2 perseant ri->ri_devcmap[(defattr >> 16) & 0xff]);
346 1.34.4.2 perseant summitfb_setup_fb(sc);
347 1.34.4.2 perseant
348 1.34.4.2 perseant if (is_console) {
349 1.34.4.2 perseant wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
350 1.34.4.2 perseant defattr);
351 1.34.4.2 perseant
352 1.34.4.2 perseant vcons_replay_msgbuf(&sc->sc_console_screen);
353 1.34.4.2 perseant }
354 1.34.4.2 perseant
355 1.34.4.2 perseant aprint_normal_dev(sc->sc_dev, "%s at %dx%d\n", sc->sc_scr.name,
356 1.34.4.2 perseant sc->sc_width, sc->sc_height);
357 1.34.4.2 perseant
358 1.34.4.2 perseant /* no suspend/resume support yet */
359 1.34.4.2 perseant pmf_device_register(sc->sc_dev, NULL, NULL);
360 1.34.4.2 perseant
361 1.34.4.2 perseant aa.console = is_console;
362 1.34.4.2 perseant aa.scrdata = &sc->sc_screenlist;
363 1.34.4.2 perseant aa.accessops = &summitfb_accessops;
364 1.34.4.2 perseant aa.accesscookie = &sc->vd;
365 1.34.4.2 perseant
366 1.34.4.2 perseant config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE);
367 1.34.4.2 perseant }
368 1.34.4.2 perseant
369 1.34.4.2 perseant /*
370 1.34.4.2 perseant * Grovel the STI ROM image.
371 1.34.4.2 perseant */
372 1.34.4.2 perseant int
373 1.34.4.2 perseant summitfb_check_rom(struct summitfb_softc *spc, struct pci_attach_args *pa)
374 1.34.4.2 perseant {
375 1.34.4.2 perseant struct sti_softc *sc = &spc->sc_base;
376 1.34.4.2 perseant pcireg_t address, mask;
377 1.34.4.2 perseant bus_space_handle_t romh;
378 1.34.4.2 perseant bus_size_t romsize, subsize, stiromsize;
379 1.34.4.2 perseant bus_addr_t selected, offs, suboffs;
380 1.34.4.2 perseant uint32_t tmp;
381 1.34.4.2 perseant int i;
382 1.34.4.2 perseant int rc;
383 1.34.4.2 perseant
384 1.34.4.2 perseant /* sort of inline sti_pci_enable_rom(sc) */
385 1.34.4.2 perseant address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM);
386 1.34.4.2 perseant pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM,
387 1.34.4.2 perseant ~PCI_MAPREG_ROM_ENABLE);
388 1.34.4.2 perseant mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM);
389 1.34.4.2 perseant address |= PCI_MAPREG_ROM_ENABLE;
390 1.34.4.2 perseant pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, address);
391 1.34.4.2 perseant sc->sc_flags |= STI_ROM_ENABLED;
392 1.34.4.2 perseant
393 1.34.4.2 perseant /*
394 1.34.4.2 perseant * Map the complete ROM for now.
395 1.34.4.2 perseant */
396 1.34.4.2 perseant romsize = PCI_ROM_SIZE(mask);
397 1.34.4.2 perseant DPRINTF(("%s: mapping rom @ %lx for %lx\n", __func__,
398 1.34.4.2 perseant (long)PCI_MAPREG_ROM_ADDR(address), (long)romsize));
399 1.34.4.2 perseant
400 1.34.4.2 perseant rc = bus_space_map(pa->pa_memt, PCI_MAPREG_ROM_ADDR(address), romsize,
401 1.34.4.2 perseant 0, &romh);
402 1.34.4.2 perseant if (rc != 0) {
403 1.34.4.2 perseant aprint_error_dev(sc->sc_dev, "can't map PCI ROM (%d)\n", rc);
404 1.34.4.2 perseant goto fail2;
405 1.34.4.2 perseant }
406 1.34.4.2 perseant
407 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
408 1.34.4.2 perseant
409 1.34.4.2 perseant /*
410 1.34.4.2 perseant * Iterate over the ROM images, pick the best candidate.
411 1.34.4.2 perseant */
412 1.34.4.2 perseant selected = (bus_addr_t)-1;
413 1.34.4.2 perseant for (offs = 0; offs < romsize; offs += subsize) {
414 1.34.4.2 perseant summitfb_enable_rom_internal(spc);
415 1.34.4.2 perseant /*
416 1.34.4.2 perseant * Check for a valid ROM header.
417 1.34.4.2 perseant */
418 1.34.4.2 perseant tmp = bus_space_read_4(pa->pa_memt, romh, offs + 0);
419 1.34.4.2 perseant tmp = le32toh(tmp);
420 1.34.4.2 perseant if (tmp != 0x55aa0000) {
421 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
422 1.34.4.2 perseant if (offs == 0) {
423 1.34.4.2 perseant aprint_error_dev(sc->sc_dev,
424 1.34.4.2 perseant "invalid PCI ROM header signature"
425 1.34.4.2 perseant " (%08x)\n", tmp);
426 1.34.4.2 perseant rc = EINVAL;
427 1.34.4.2 perseant }
428 1.34.4.2 perseant break;
429 1.34.4.2 perseant }
430 1.34.4.2 perseant
431 1.34.4.2 perseant /*
432 1.34.4.2 perseant * Check ROM type.
433 1.34.4.2 perseant */
434 1.34.4.2 perseant tmp = bus_space_read_4(pa->pa_memt, romh, offs + 4);
435 1.34.4.2 perseant tmp = le32toh(tmp);
436 1.34.4.2 perseant if (tmp != 0x00000001) { /* 1 == STI ROM */
437 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
438 1.34.4.2 perseant if (offs == 0) {
439 1.34.4.2 perseant aprint_error_dev(sc->sc_dev,
440 1.34.4.2 perseant "invalid PCI ROM type (%08x)\n", tmp);
441 1.34.4.2 perseant rc = EINVAL;
442 1.34.4.2 perseant }
443 1.34.4.2 perseant break;
444 1.34.4.2 perseant }
445 1.34.4.2 perseant
446 1.34.4.2 perseant subsize = (bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
447 1.34.4.2 perseant offs + 0x0c);
448 1.34.4.2 perseant subsize <<= 9;
449 1.34.4.2 perseant
450 1.34.4.2 perseant #ifdef SUMMITFB_DEBUG
451 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
452 1.34.4.2 perseant DPRINTF(("ROM offset %08x size %08x type %08x",
453 1.34.4.2 perseant (u_int)offs, (u_int)subsize, tmp));
454 1.34.4.2 perseant summitfb_enable_rom_internal(spc);
455 1.34.4.2 perseant #endif
456 1.34.4.2 perseant
457 1.34.4.2 perseant /*
458 1.34.4.2 perseant * Check for a valid ROM data structure.
459 1.34.4.2 perseant * We do not need it except to know what architecture the ROM
460 1.34.4.2 perseant * code is for.
461 1.34.4.2 perseant */
462 1.34.4.2 perseant
463 1.34.4.2 perseant suboffs = offs + bus_space_read_2(pa->pa_memt, romh,
464 1.34.4.2 perseant offs + 0x18);
465 1.34.4.2 perseant tmp = bus_space_read_4(pa->pa_memt, romh, suboffs + 0);
466 1.34.4.2 perseant tmp = le32toh(tmp);
467 1.34.4.2 perseant if (tmp != 0x50434952) { /* PCIR */
468 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
469 1.34.4.2 perseant if (offs == 0) {
470 1.34.4.2 perseant aprint_error_dev(sc->sc_dev, "invalid PCI data"
471 1.34.4.2 perseant " signature (%08x)\n", tmp);
472 1.34.4.2 perseant rc = EINVAL;
473 1.34.4.2 perseant } else {
474 1.34.4.2 perseant DPRINTF((" invalid PCI data signature %08x\n",
475 1.34.4.2 perseant tmp));
476 1.34.4.2 perseant continue;
477 1.34.4.2 perseant }
478 1.34.4.2 perseant }
479 1.34.4.2 perseant
480 1.34.4.2 perseant tmp = bus_space_read_1(pa->pa_memt, romh, suboffs + 0x14);
481 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
482 1.34.4.2 perseant DPRINTF((" code %02x", tmp));
483 1.34.4.2 perseant
484 1.34.4.2 perseant switch (tmp) {
485 1.34.4.2 perseant #ifdef __hppa__
486 1.34.4.2 perseant case 0x10:
487 1.34.4.2 perseant if (selected == (bus_addr_t)-1)
488 1.34.4.2 perseant selected = offs;
489 1.34.4.2 perseant break;
490 1.34.4.2 perseant #endif
491 1.34.4.2 perseant #ifdef __i386__
492 1.34.4.2 perseant case 0x00:
493 1.34.4.2 perseant if (selected == (bus_addr_t)-1)
494 1.34.4.2 perseant selected = offs;
495 1.34.4.2 perseant break;
496 1.34.4.2 perseant #endif
497 1.34.4.2 perseant default:
498 1.34.4.2 perseant DPRINTF((" (wrong architecture)"));
499 1.34.4.2 perseant break;
500 1.34.4.2 perseant }
501 1.34.4.2 perseant DPRINTF(("%s\n", selected == offs ? " -> SELECTED" : ""));
502 1.34.4.2 perseant }
503 1.34.4.2 perseant
504 1.34.4.2 perseant if (selected == (bus_addr_t)-1) {
505 1.34.4.2 perseant if (rc == 0) {
506 1.34.4.2 perseant aprint_error_dev(sc->sc_dev, "found no ROM with "
507 1.34.4.2 perseant "correct microcode architecture\n");
508 1.34.4.2 perseant rc = ENOEXEC;
509 1.34.4.2 perseant }
510 1.34.4.2 perseant goto fail;
511 1.34.4.2 perseant }
512 1.34.4.2 perseant
513 1.34.4.2 perseant /*
514 1.34.4.2 perseant * Read the STI region BAR assignments.
515 1.34.4.2 perseant */
516 1.34.4.2 perseant
517 1.34.4.2 perseant summitfb_enable_rom_internal(spc);
518 1.34.4.2 perseant offs = selected + bus_space_read_2(pa->pa_memt, romh, selected + 0x0e);
519 1.34.4.2 perseant for (i = 0; i < STI_REGION_MAX; i++) {
520 1.34.4.2 perseant rc = summitfb_readbar(sc, pa, i,
521 1.34.4.2 perseant bus_space_read_1(pa->pa_memt, romh, offs + i));
522 1.34.4.2 perseant if (rc != 0)
523 1.34.4.2 perseant goto fail;
524 1.34.4.2 perseant }
525 1.34.4.2 perseant
526 1.34.4.2 perseant /*
527 1.34.4.2 perseant * Find out where the STI ROM itself lies, and its size.
528 1.34.4.2 perseant */
529 1.34.4.2 perseant
530 1.34.4.2 perseant offs = selected +
531 1.34.4.2 perseant bus_space_read_4(pa->pa_memt, romh, selected + 0x08);
532 1.34.4.2 perseant stiromsize = bus_space_read_4(pa->pa_memt, romh, offs + 0x18);
533 1.34.4.2 perseant stiromsize = le32toh(stiromsize);
534 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
535 1.34.4.2 perseant
536 1.34.4.2 perseant /*
537 1.34.4.2 perseant * Replace our mapping with a smaller mapping of only the area
538 1.34.4.2 perseant * we are interested in.
539 1.34.4.2 perseant */
540 1.34.4.2 perseant
541 1.34.4.2 perseant DPRINTF(("remapping rom @ %lx for %lx\n",
542 1.34.4.2 perseant (long)(PCI_MAPREG_ROM_ADDR(address) + offs), (long)stiromsize));
543 1.34.4.2 perseant bus_space_unmap(pa->pa_memt, romh, romsize);
544 1.34.4.2 perseant rc = bus_space_map(pa->pa_memt, PCI_MAPREG_ROM_ADDR(address) + offs,
545 1.34.4.2 perseant stiromsize, 0, &spc->sc_romh);
546 1.34.4.2 perseant if (rc != 0) {
547 1.34.4.2 perseant aprint_error_dev(sc->sc_dev, "can't map STI ROM (%d)\n",
548 1.34.4.2 perseant rc);
549 1.34.4.2 perseant goto fail2;
550 1.34.4.2 perseant }
551 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
552 1.34.4.2 perseant sc->sc_flags &= ~STI_ROM_ENABLED;
553 1.34.4.2 perseant
554 1.34.4.2 perseant return 0;
555 1.34.4.2 perseant
556 1.34.4.2 perseant fail:
557 1.34.4.2 perseant bus_space_unmap(pa->pa_memt, romh, romsize);
558 1.34.4.2 perseant fail2:
559 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
560 1.34.4.2 perseant
561 1.34.4.2 perseant return rc;
562 1.34.4.2 perseant }
563 1.34.4.2 perseant
564 1.34.4.2 perseant /*
565 1.34.4.2 perseant * Decode a BAR register.
566 1.34.4.2 perseant */
567 1.34.4.2 perseant int
568 1.34.4.2 perseant summitfb_readbar(struct sti_softc *sc, struct pci_attach_args *pa,
569 1.34.4.2 perseant u_int region, int bar)
570 1.34.4.2 perseant {
571 1.34.4.2 perseant bus_addr_t addr;
572 1.34.4.2 perseant bus_size_t size;
573 1.34.4.2 perseant uint32_t cf;
574 1.34.4.2 perseant int rc;
575 1.34.4.2 perseant
576 1.34.4.2 perseant if (bar == 0) {
577 1.34.4.2 perseant sc->bases[region] = 0;
578 1.34.4.2 perseant return 0;
579 1.34.4.2 perseant }
580 1.34.4.2 perseant
581 1.34.4.2 perseant #ifdef DIAGNOSTIC
582 1.34.4.2 perseant if (bar < PCI_MAPREG_START || bar > PCI_MAPREG_PPB_END) {
583 1.34.4.2 perseant summitfb_disable_rom(sc);
584 1.34.4.2 perseant printf("%s: unexpected bar %02x for region %d\n",
585 1.34.4.2 perseant device_xname(sc->sc_dev), bar, region);
586 1.34.4.2 perseant summitfb_enable_rom(sc);
587 1.34.4.2 perseant }
588 1.34.4.2 perseant #endif
589 1.34.4.2 perseant
590 1.34.4.2 perseant cf = pci_conf_read(pa->pa_pc, pa->pa_tag, bar);
591 1.34.4.2 perseant
592 1.34.4.2 perseant rc = pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, PCI_MAPREG_TYPE(cf),
593 1.34.4.2 perseant &addr, &size, NULL);
594 1.34.4.2 perseant
595 1.34.4.2 perseant if (rc != 0) {
596 1.34.4.2 perseant summitfb_disable_rom(sc);
597 1.34.4.2 perseant aprint_error_dev(sc->sc_dev, "invalid bar %02x"
598 1.34.4.2 perseant " for region %d\n",
599 1.34.4.2 perseant bar, region);
600 1.34.4.2 perseant summitfb_enable_rom(sc);
601 1.34.4.2 perseant return rc;
602 1.34.4.2 perseant }
603 1.34.4.2 perseant
604 1.34.4.2 perseant sc->bases[region] = addr;
605 1.34.4.2 perseant return 0;
606 1.34.4.2 perseant }
607 1.34.4.2 perseant
608 1.34.4.2 perseant /*
609 1.34.4.2 perseant * Enable PCI ROM.
610 1.34.4.2 perseant */
611 1.34.4.2 perseant void
612 1.34.4.2 perseant summitfb_enable_rom_internal(struct summitfb_softc *spc)
613 1.34.4.2 perseant {
614 1.34.4.2 perseant pcireg_t address;
615 1.34.4.2 perseant
616 1.34.4.2 perseant KASSERT(spc != NULL);
617 1.34.4.2 perseant
618 1.34.4.2 perseant address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM);
619 1.34.4.2 perseant address |= PCI_MAPREG_ROM_ENABLE;
620 1.34.4.2 perseant pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address);
621 1.34.4.2 perseant }
622 1.34.4.2 perseant
623 1.34.4.2 perseant void
624 1.34.4.2 perseant summitfb_enable_rom(struct sti_softc *sc)
625 1.34.4.2 perseant {
626 1.34.4.2 perseant struct summitfb_softc *spc = device_private(sc->sc_dev);
627 1.34.4.2 perseant
628 1.34.4.2 perseant if (!ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
629 1.34.4.2 perseant summitfb_enable_rom_internal(spc);
630 1.34.4.2 perseant }
631 1.34.4.2 perseant SET(sc->sc_flags, STI_ROM_ENABLED);
632 1.34.4.2 perseant }
633 1.34.4.2 perseant
634 1.34.4.2 perseant /*
635 1.34.4.2 perseant * Disable PCI ROM.
636 1.34.4.2 perseant */
637 1.34.4.2 perseant void
638 1.34.4.2 perseant summitfb_disable_rom_internal(struct summitfb_softc *spc)
639 1.34.4.2 perseant {
640 1.34.4.2 perseant pcireg_t address;
641 1.34.4.2 perseant
642 1.34.4.2 perseant KASSERT(spc != NULL);
643 1.34.4.2 perseant
644 1.34.4.2 perseant address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM);
645 1.34.4.2 perseant address &= ~PCI_MAPREG_ROM_ENABLE;
646 1.34.4.2 perseant pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address);
647 1.34.4.2 perseant }
648 1.34.4.2 perseant
649 1.34.4.2 perseant void
650 1.34.4.2 perseant summitfb_disable_rom(struct sti_softc *sc)
651 1.34.4.2 perseant {
652 1.34.4.2 perseant struct summitfb_softc *spc = device_private(sc->sc_dev);
653 1.34.4.2 perseant
654 1.34.4.2 perseant if (ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
655 1.34.4.2 perseant summitfb_disable_rom_internal(spc);
656 1.34.4.2 perseant }
657 1.34.4.2 perseant CLR(sc->sc_flags, STI_ROM_ENABLED);
658 1.34.4.2 perseant }
659 1.34.4.2 perseant
660 1.34.4.2 perseant static inline void
661 1.34.4.2 perseant summitfb_wait(struct summitfb_softc *sc)
662 1.34.4.2 perseant {
663 1.34.4.2 perseant
664 1.34.4.2 perseant while (summitfb_read4(sc, VISFX_STATUS) != 0)
665 1.34.4.2 perseant continue;
666 1.34.4.2 perseant }
667 1.34.4.2 perseant
668 1.34.4.2 perseant static inline void
669 1.34.4.2 perseant summitfb_setup_fb(struct summitfb_softc *sc)
670 1.34.4.2 perseant {
671 1.34.4.2 perseant
672 1.34.4.2 perseant summitfb_wait(sc);
673 1.34.4.2 perseant if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
674 1.34.4.2 perseant summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN);
675 1.34.4.2 perseant summitfb_read_mode(sc, VISFX_WRITE_MODE_PLAIN);
676 1.34.4.2 perseant summitfb_write4(sc, VISFX_APERTURE_ACCESS, VISFX_DEPTH_8);
677 1.34.4.2 perseant /* make overlay opaque */
678 1.34.4.2 perseant summitfb_write4(sc, VISFX_OTR, OTR_T | OTR_L1 | OTR_L0);
679 1.34.4.2 perseant } else {
680 1.34.4.2 perseant summitfb_write_mode(sc, OTC01 | BIN8F | BUFFL);
681 1.34.4.2 perseant summitfb_read_mode(sc, OTC01 | BIN8F | BUFFL);
682 1.34.4.2 perseant summitfb_write4(sc, VISFX_APERTURE_ACCESS, VISFX_DEPTH_32);
683 1.34.4.2 perseant /* make overlay transparent */
684 1.34.4.2 perseant summitfb_write4(sc, VISFX_OTR, OTR_A);
685 1.34.4.2 perseant }
686 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, RopSrc);
687 1.34.4.2 perseant }
688 1.34.4.2 perseant
689 1.34.4.2 perseant void
690 1.34.4.2 perseant summitfb_setup(struct summitfb_softc *sc)
691 1.34.4.2 perseant {
692 1.34.4.2 perseant int i;
693 1.34.4.2 perseant
694 1.34.4.2 perseant sc->sc_hot_x = 0;
695 1.34.4.2 perseant sc->sc_hot_y = 0;
696 1.34.4.2 perseant sc->sc_enabled = 0;
697 1.34.4.2 perseant sc->sc_video_on = 1;
698 1.34.4.2 perseant
699 1.34.4.2 perseant summitfb_wait(sc);
700 1.34.4.2 perseant #if 1
701 1.34.4.2 perseant /* these control byte swapping */
702 1.34.4.2 perseant summitfb_write4(sc, 0xb08044, 0x1b); /* MFU_BSCTD */
703 1.34.4.2 perseant summitfb_write4(sc, 0xb08048, 0x1b); /* MFU_BSCCTL */
704 1.34.4.2 perseant
705 1.34.4.2 perseant summitfb_write4(sc, 0x920860, 0xe4); /* FBC_RBS */
706 1.34.4.2 perseant summitfb_write4(sc, 0x921114, 0); /* CPE, clip plane enable */
707 1.34.4.2 perseant summitfb_write4(sc, 0x9211d8, 0); /* FCDA */
708 1.34.4.2 perseant
709 1.34.4.2 perseant summitfb_write4(sc, 0xa00818, 0); /* WORG window origin */
710 1.34.4.2 perseant summitfb_write4(sc, 0xa0081c, 0); /* FBS front buffer select*/
711 1.34.4.2 perseant summitfb_write4(sc, 0xa00850, 0); /* MISC_CTL */
712 1.34.4.2 perseant summitfb_write4(sc, 0xa0086c, 0); /* WCE window clipping enable */
713 1.34.4.2 perseant #endif
714 1.34.4.2 perseant /* initialize drawiing engine */
715 1.34.4.2 perseant summitfb_wait(sc);
716 1.34.4.2 perseant summitfb_write4(sc, VISFX_CONTROL, 0); // clear WFC
717 1.34.4.2 perseant summitfb_write4(sc, VISFX_APERTURE_ACCESS, VISFX_DEPTH_8);
718 1.34.4.2 perseant summitfb_write4(sc, VISFX_PIXEL_MASK, 0xffffffff);
719 1.34.4.2 perseant summitfb_write4(sc, VISFX_PLANE_MASK, 0xffffffff);
720 1.34.4.2 perseant summitfb_write4(sc, VISFX_FOE, FOE_BLEND_ROP);
721 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, RopSrc);
722 1.34.4.2 perseant summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN);
723 1.34.4.2 perseant summitfb_read_mode(sc, OTC04 | BIN8I | BUFovl);
724 1.34.4.2 perseant summitfb_write4(sc, VISFX_CLIP_TL, 0);
725 1.34.4.2 perseant summitfb_write4(sc, VISFX_CLIP_WH,
726 1.34.4.2 perseant ((sc->sc_scr.fbwidth) << 16) | (sc->sc_scr.fbheight));
727 1.34.4.2 perseant /* turn off the cursor sprite */
728 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_POS, 0);
729 1.34.4.2 perseant /* disable throttling by moving the throttle window way off screen */
730 1.34.4.2 perseant summitfb_write4(sc, VISFX_TCR, 0x10001000);
731 1.34.4.2 perseant
732 1.34.4.2 perseant /* make sure the overlay is opaque */
733 1.34.4.2 perseant summitfb_write4(sc, VISFX_OTR, OTR_T | OTR_L1 | OTR_L0);
734 1.34.4.2 perseant
735 1.34.4.2 perseant /*
736 1.34.4.2 perseant * initialize XLUT, I mean attribute table
737 1.34.4.2 perseant * set all to 24bit, CFS1
738 1.34.4.2 perseant */
739 1.34.4.2 perseant for (i = 0; i < 16; i++)
740 1.34.4.2 perseant summitfb_write4(sc, VISFX_IAA(i), IAA_8F | IAA_CFS1);
741 1.34.4.2 perseant /* RGB8, no LUT */
742 1.34.4.2 perseant summitfb_write4(sc, VISFX_CFS(1), CFS_8F | CFS_BYPASS);
743 1.34.4.2 perseant /* overlay is 8bit, uses LUT 0 */
744 1.34.4.2 perseant summitfb_write4(sc, VISFX_CFS(16), CFS_8I | CFS_LUT0);
745 1.34.4.2 perseant summitfb_write4(sc, VISFX_CFS(17), CFS_8I | CFS_LUT0);
746 1.34.4.2 perseant
747 1.34.4.2 perseant /* zero the attribute plane */
748 1.34.4.2 perseant summitfb_write_mode(sc, OTC04 | BINapln);
749 1.34.4.2 perseant summitfb_wait_fifo(sc, 12);
750 1.34.4.2 perseant summitfb_write4(sc, VISFX_PLANE_MASK, 0xff);
751 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, 0); /* GXclear */
752 1.34.4.2 perseant summitfb_write4(sc, VISFX_FG_COLOUR, 0);
753 1.34.4.2 perseant summitfb_write4(sc, VISFX_START, 0);
754 1.34.4.2 perseant summitfb_write4(sc, VISFX_SIZE, (sc->sc_width << 16) | sc->sc_height);
755 1.34.4.2 perseant summitfb_wait(sc);
756 1.34.4.2 perseant summitfb_write4(sc, VISFX_PLANE_MASK, 0xffffffff);
757 1.34.4.2 perseant
758 1.34.4.2 perseant /* turn off force attr so the above takes effect */
759 1.34.4.2 perseant summitfb_write4(sc, VISFX_FATTR, 0);
760 1.34.4.2 perseant
761 1.34.4.2 perseant summitfb_setup_fb(sc);
762 1.34.4.2 perseant }
763 1.34.4.2 perseant
764 1.34.4.2 perseant static int
765 1.34.4.2 perseant summitfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
766 1.34.4.2 perseant struct lwp *l)
767 1.34.4.2 perseant {
768 1.34.4.2 perseant struct vcons_data *vd = v;
769 1.34.4.2 perseant struct summitfb_softc *sc = vd->cookie;
770 1.34.4.2 perseant struct wsdisplay_fbinfo *wdf;
771 1.34.4.2 perseant struct vcons_screen *ms = vd->active;
772 1.34.4.2 perseant
773 1.34.4.2 perseant switch (cmd) {
774 1.34.4.2 perseant case WSDISPLAYIO_GTYPE:
775 1.34.4.2 perseant *(u_int *)data = WSDISPLAY_TYPE_STI;
776 1.34.4.2 perseant return 0;
777 1.34.4.2 perseant
778 1.34.4.2 perseant case GCID:
779 1.34.4.2 perseant *(u_int *)data = sc->sc_scr.scr_rom->rom_dd.dd_grid[0];
780 1.34.4.2 perseant return 0;
781 1.34.4.2 perseant
782 1.34.4.2 perseant /* PCI config read/write passthrough. */
783 1.34.4.2 perseant case PCI_IOC_CFGREAD:
784 1.34.4.2 perseant case PCI_IOC_CFGWRITE:
785 1.34.4.2 perseant return pci_devioctl(sc->sc_pc, sc->sc_tag,
786 1.34.4.2 perseant cmd, data, flag, l);
787 1.34.4.2 perseant
788 1.34.4.2 perseant case WSDISPLAYIO_GET_BUSID:
789 1.34.4.2 perseant return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc,
790 1.34.4.2 perseant sc->sc_tag, data);
791 1.34.4.2 perseant
792 1.34.4.2 perseant case WSDISPLAYIO_GINFO:
793 1.34.4.2 perseant if (ms == NULL)
794 1.34.4.2 perseant return ENODEV;
795 1.34.4.2 perseant wdf = data;
796 1.34.4.2 perseant wdf->height = ms->scr_ri.ri_height;
797 1.34.4.2 perseant wdf->width = ms->scr_ri.ri_width;
798 1.34.4.2 perseant wdf->depth = ms->scr_ri.ri_depth;
799 1.34.4.2 perseant wdf->cmsize = 256;
800 1.34.4.2 perseant return 0;
801 1.34.4.2 perseant
802 1.34.4.2 perseant case WSDISPLAYIO_GETCMAP:
803 1.34.4.2 perseant return summitfb_getcmap(sc,
804 1.34.4.2 perseant (struct wsdisplay_cmap *)data);
805 1.34.4.2 perseant
806 1.34.4.2 perseant case WSDISPLAYIO_PUTCMAP:
807 1.34.4.2 perseant return summitfb_putcmap(sc,
808 1.34.4.2 perseant (struct wsdisplay_cmap *)data);
809 1.34.4.2 perseant
810 1.34.4.2 perseant case WSDISPLAYIO_LINEBYTES:
811 1.34.4.2 perseant *(u_int *)data = 2048;
812 1.34.4.2 perseant return 0;
813 1.34.4.2 perseant
814 1.34.4.2 perseant case WSDISPLAYIO_SMODE: {
815 1.34.4.2 perseant int new_mode = *(int *)data;
816 1.34.4.2 perseant
817 1.34.4.2 perseant if (new_mode != sc->sc_mode) {
818 1.34.4.2 perseant sc->sc_mode = new_mode;
819 1.34.4.2 perseant if(new_mode == WSDISPLAYIO_MODE_EMUL) {
820 1.34.4.2 perseant summitfb_setup(sc);
821 1.34.4.2 perseant summitfb_restore_palette(sc);
822 1.34.4.2 perseant glyphcache_wipe(&sc->sc_gc);
823 1.34.4.2 perseant summitfb_rectfill(sc, 0, 0, sc->sc_width,
824 1.34.4.2 perseant sc->sc_height, ms->scr_ri.ri_devcmap[
825 1.34.4.2 perseant (ms->scr_defattr >> 16) & 0xff]);
826 1.34.4.2 perseant vcons_redraw_screen(ms);
827 1.34.4.2 perseant summitfb_set_video(sc, 1);
828 1.34.4.2 perseant } else
829 1.34.4.2 perseant summitfb_clearfb(sc);
830 1.34.4.2 perseant summitfb_setup_fb(sc);
831 1.34.4.2 perseant }
832 1.34.4.2 perseant return 0;
833 1.34.4.2 perseant }
834 1.34.4.2 perseant
835 1.34.4.2 perseant case WSDISPLAYIO_GET_FBINFO: {
836 1.34.4.2 perseant struct wsdisplayio_fbinfo *fbi = data;
837 1.34.4.2 perseant int ret;
838 1.34.4.2 perseant
839 1.34.4.2 perseant ret = wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
840 1.34.4.2 perseant //fbi->fbi_fbsize = sc->sc_height * 2048;
841 1.34.4.2 perseant fbi->fbi_stride = 8192;
842 1.34.4.2 perseant fbi->fbi_bitsperpixel = 32;
843 1.34.4.2 perseant fbi->fbi_pixeltype = WSFB_RGB;
844 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.red_offset = 16;
845 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.red_size = 8;
846 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.green_offset = 8;
847 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.green_size = 8;
848 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0;
849 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8;
850 1.34.4.2 perseant fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0;
851 1.34.4.2 perseant fbi->fbi_fbsize = sc->sc_scr.fbheight * 8192;
852 1.34.4.2 perseant return ret;
853 1.34.4.2 perseant }
854 1.34.4.2 perseant
855 1.34.4.2 perseant case WSDISPLAYIO_GCURPOS: {
856 1.34.4.2 perseant struct wsdisplay_curpos *cp = data;
857 1.34.4.2 perseant
858 1.34.4.2 perseant cp->x = sc->sc_cursor_x;
859 1.34.4.2 perseant cp->y = sc->sc_cursor_y;
860 1.34.4.2 perseant return 0;
861 1.34.4.2 perseant }
862 1.34.4.2 perseant
863 1.34.4.2 perseant case WSDISPLAYIO_SCURPOS: {
864 1.34.4.2 perseant struct wsdisplay_curpos *cp = data;
865 1.34.4.2 perseant
866 1.34.4.2 perseant summitfb_move_cursor(sc, cp->x, cp->y);
867 1.34.4.2 perseant return 0;
868 1.34.4.2 perseant }
869 1.34.4.2 perseant
870 1.34.4.2 perseant case WSDISPLAYIO_GCURMAX: {
871 1.34.4.2 perseant struct wsdisplay_curpos *cp = data;
872 1.34.4.2 perseant
873 1.34.4.2 perseant cp->x = 64;
874 1.34.4.2 perseant cp->y = 64;
875 1.34.4.2 perseant return 0;
876 1.34.4.2 perseant }
877 1.34.4.2 perseant
878 1.34.4.2 perseant case WSDISPLAYIO_SCURSOR: {
879 1.34.4.2 perseant struct wsdisplay_cursor *cursor = data;
880 1.34.4.2 perseant
881 1.34.4.2 perseant return summitfb_do_cursor(sc, cursor);
882 1.34.4.2 perseant }
883 1.34.4.2 perseant
884 1.34.4.2 perseant case WSDISPLAYIO_SVIDEO:
885 1.34.4.2 perseant summitfb_set_video(sc, *(int *)data);
886 1.34.4.2 perseant return 0;
887 1.34.4.2 perseant case WSDISPLAYIO_GVIDEO:
888 1.34.4.2 perseant *(u_int *)data = sc->sc_video_on ?
889 1.34.4.2 perseant WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF;
890 1.34.4.2 perseant return 0;
891 1.34.4.2 perseant }
892 1.34.4.2 perseant return EPASSTHROUGH;
893 1.34.4.2 perseant }
894 1.34.4.2 perseant
895 1.34.4.2 perseant static paddr_t
896 1.34.4.2 perseant summitfb_mmap(void *v, void *vs, off_t offset, int prot)
897 1.34.4.2 perseant {
898 1.34.4.2 perseant struct vcons_data *vd = v;
899 1.34.4.2 perseant struct summitfb_softc *sc = vd->cookie;
900 1.34.4.2 perseant struct sti_rom *rom = sc->sc_base.sc_rom;
901 1.34.4.2 perseant paddr_t pa = -1;
902 1.34.4.2 perseant
903 1.34.4.2 perseant if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
904 1.34.4.2 perseant return -1;
905 1.34.4.2 perseant
906 1.34.4.2 perseant if (offset >= 0 && offset < 0x01000000) {
907 1.34.4.2 perseant /* framebuffer */
908 1.34.4.2 perseant pa = bus_space_mmap(rom->memt, sc->sc_scr.fbaddr, offset,
909 1.34.4.2 perseant prot, BUS_SPACE_MAP_LINEAR);
910 1.34.4.2 perseant } else if (offset >= 0x80000000 && offset < 0x81000000) {
911 1.34.4.2 perseant /* blitter registers etc. */
912 1.34.4.2 perseant pa = bus_space_mmap(rom->memt, rom->regh[0],
913 1.34.4.2 perseant offset - 0x80000000, prot, BUS_SPACE_MAP_LINEAR);
914 1.34.4.2 perseant }
915 1.34.4.2 perseant
916 1.34.4.2 perseant return pa;
917 1.34.4.2 perseant }
918 1.34.4.2 perseant
919 1.34.4.2 perseant static void
920 1.34.4.2 perseant summitfb_init_screen(void *cookie, struct vcons_screen *scr,
921 1.34.4.2 perseant int existing, long *defattr)
922 1.34.4.2 perseant {
923 1.34.4.2 perseant struct summitfb_softc *sc = cookie;
924 1.34.4.2 perseant struct rasops_info *ri = &scr->scr_ri;
925 1.34.4.2 perseant
926 1.34.4.2 perseant ri->ri_depth = 8;
927 1.34.4.2 perseant ri->ri_width = sc->sc_width;
928 1.34.4.2 perseant ri->ri_height = sc->sc_height;
929 1.34.4.2 perseant ri->ri_stride = 2048;
930 1.34.4.2 perseant ri->ri_flg = RI_CENTER | RI_8BIT_IS_RGB
931 1.34.4.2 perseant | RI_ENABLE_ALPHA | RI_PREFER_ALPHA
932 1.34.4.2 perseant ;
933 1.34.4.2 perseant
934 1.34.4.2 perseant ri->ri_bits = (void *)sc->sc_scr.fbaddr;
935 1.34.4.2 perseant rasops_init(ri, 0, 0);
936 1.34.4.2 perseant ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE |
937 1.34.4.2 perseant WSSCREEN_RESIZE;
938 1.34.4.2 perseant scr->scr_flags |= VCONS_LOADFONT;
939 1.34.4.2 perseant
940 1.34.4.2 perseant rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
941 1.34.4.2 perseant sc->sc_width / ri->ri_font->fontwidth);
942 1.34.4.2 perseant
943 1.34.4.2 perseant ri->ri_hw = scr;
944 1.34.4.2 perseant
945 1.34.4.2 perseant ri->ri_ops.copyrows = summitfb_copyrows;
946 1.34.4.2 perseant ri->ri_ops.copycols = summitfb_copycols;
947 1.34.4.2 perseant ri->ri_ops.eraserows = summitfb_eraserows;
948 1.34.4.2 perseant ri->ri_ops.erasecols = summitfb_erasecols;
949 1.34.4.2 perseant ri->ri_ops.cursor = summitfb_cursor;
950 1.34.4.2 perseant sc->sc_font = NULL;
951 1.34.4.2 perseant if (FONT_IS_ALPHA(ri->ri_font)) {
952 1.34.4.2 perseant ri->ri_ops.putchar = summitfb_putchar_aa;
953 1.34.4.2 perseant } else
954 1.34.4.2 perseant ri->ri_ops.putchar = summitfb_putchar;
955 1.34.4.2 perseant }
956 1.34.4.2 perseant
957 1.34.4.2 perseant static int
958 1.34.4.2 perseant summitfb_putcmap(struct summitfb_softc *sc, struct wsdisplay_cmap *cm)
959 1.34.4.2 perseant {
960 1.34.4.2 perseant u_char *r, *g, *b;
961 1.34.4.2 perseant u_int index = cm->index;
962 1.34.4.2 perseant u_int count = cm->count;
963 1.34.4.2 perseant int i, error;
964 1.34.4.2 perseant u_char rbuf[256], gbuf[256], bbuf[256];
965 1.34.4.2 perseant
966 1.34.4.2 perseant if (cm->index >= 256 || cm->count > 256 ||
967 1.34.4.2 perseant (cm->index + cm->count) > 256)
968 1.34.4.2 perseant return EINVAL;
969 1.34.4.2 perseant error = copyin(cm->red, &rbuf[index], count);
970 1.34.4.2 perseant if (error)
971 1.34.4.2 perseant return error;
972 1.34.4.2 perseant error = copyin(cm->green, &gbuf[index], count);
973 1.34.4.2 perseant if (error)
974 1.34.4.2 perseant return error;
975 1.34.4.2 perseant error = copyin(cm->blue, &bbuf[index], count);
976 1.34.4.2 perseant if (error)
977 1.34.4.2 perseant return error;
978 1.34.4.2 perseant
979 1.34.4.2 perseant memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
980 1.34.4.2 perseant memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
981 1.34.4.2 perseant memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
982 1.34.4.2 perseant
983 1.34.4.2 perseant r = &sc->sc_cmap_red[index];
984 1.34.4.2 perseant g = &sc->sc_cmap_green[index];
985 1.34.4.2 perseant b = &sc->sc_cmap_blue[index];
986 1.34.4.2 perseant
987 1.34.4.2 perseant for (i = 0; i < count; i++) {
988 1.34.4.2 perseant summitfb_putpalreg(sc, index, *r, *g, *b);
989 1.34.4.2 perseant index++;
990 1.34.4.2 perseant r++, g++, b++;
991 1.34.4.2 perseant }
992 1.34.4.2 perseant return 0;
993 1.34.4.2 perseant }
994 1.34.4.2 perseant
995 1.34.4.2 perseant static int
996 1.34.4.2 perseant summitfb_getcmap(struct summitfb_softc *sc, struct wsdisplay_cmap *cm)
997 1.34.4.2 perseant {
998 1.34.4.2 perseant u_int index = cm->index;
999 1.34.4.2 perseant u_int count = cm->count;
1000 1.34.4.2 perseant int error;
1001 1.34.4.2 perseant
1002 1.34.4.2 perseant if (index >= 255 || count > 256 || index + count > 256)
1003 1.34.4.2 perseant return EINVAL;
1004 1.34.4.2 perseant
1005 1.34.4.2 perseant error = copyout(&sc->sc_cmap_red[index], cm->red, count);
1006 1.34.4.2 perseant if (error)
1007 1.34.4.2 perseant return error;
1008 1.34.4.2 perseant error = copyout(&sc->sc_cmap_green[index], cm->green, count);
1009 1.34.4.2 perseant if (error)
1010 1.34.4.2 perseant return error;
1011 1.34.4.2 perseant error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
1012 1.34.4.2 perseant if (error)
1013 1.34.4.2 perseant return error;
1014 1.34.4.2 perseant
1015 1.34.4.2 perseant return 0;
1016 1.34.4.2 perseant }
1017 1.34.4.2 perseant
1018 1.34.4.2 perseant static void
1019 1.34.4.2 perseant summitfb_restore_palette(struct summitfb_softc *sc)
1020 1.34.4.2 perseant {
1021 1.34.4.2 perseant uint8_t cmap[768];
1022 1.34.4.2 perseant int i, j;
1023 1.34.4.2 perseant
1024 1.34.4.2 perseant j = 0;
1025 1.34.4.2 perseant rasops_get_cmap(&sc->sc_console_screen.scr_ri, cmap, sizeof(cmap));
1026 1.34.4.2 perseant for (i = 0; i < 256; i++) {
1027 1.34.4.2 perseant sc->sc_cmap_red[i] = cmap[j];
1028 1.34.4.2 perseant sc->sc_cmap_green[i] = cmap[j + 1];
1029 1.34.4.2 perseant sc->sc_cmap_blue[i] = cmap[j + 2];
1030 1.34.4.2 perseant summitfb_putpalreg(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]);
1031 1.34.4.2 perseant j += 3;
1032 1.34.4.2 perseant }
1033 1.34.4.2 perseant for (i = 0; i < 16; i++) {
1034 1.34.4.2 perseant sc->sc_palette[i] = (rasops_cmap[i * 3] << 16) |
1035 1.34.4.2 perseant (rasops_cmap[i * 3 + 1] << 8) |
1036 1.34.4.2 perseant rasops_cmap[i * 3 + 2];
1037 1.34.4.2 perseant }
1038 1.34.4.2 perseant
1039 1.34.4.2 perseant }
1040 1.34.4.2 perseant
1041 1.34.4.2 perseant static int
1042 1.34.4.2 perseant summitfb_putpalreg(struct summitfb_softc *sc, uint8_t idx,
1043 1.34.4.2 perseant uint8_t r, uint8_t g, uint8_t b)
1044 1.34.4.2 perseant {
1045 1.34.4.2 perseant
1046 1.34.4.2 perseant summitfb_write4(sc, VISFX_COLOR_INDEX, idx);
1047 1.34.4.2 perseant summitfb_write4(sc, VISFX_COLOR_VALUE, (r << 16) | ( g << 8) | b);
1048 1.34.4.2 perseant summitfb_write4(sc, VISFX_COLOR_MASK, 0xff);
1049 1.34.4.2 perseant return 0;
1050 1.34.4.2 perseant }
1051 1.34.4.2 perseant
1052 1.34.4.2 perseant static inline void
1053 1.34.4.2 perseant summitfb_wait_fifo(struct summitfb_softc *sc, uint32_t slots)
1054 1.34.4.2 perseant {
1055 1.34.4.2 perseant uint32_t reg;
1056 1.34.4.2 perseant
1057 1.34.4.2 perseant do {
1058 1.34.4.2 perseant reg = summitfb_read4(sc, VISFX_FIFO);
1059 1.34.4.2 perseant } while (reg < slots);
1060 1.34.4.2 perseant }
1061 1.34.4.2 perseant
1062 1.34.4.2 perseant static void
1063 1.34.4.2 perseant summitfb_clearfb(struct summitfb_softc *sc)
1064 1.34.4.2 perseant {
1065 1.34.4.2 perseant summitfb_write_mode(sc, OTC32 | BIN8F | BUFBL | BUFFL | 0x8c0);
1066 1.34.4.2 perseant summitfb_wait_fifo(sc, 10);
1067 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, RopSrc);
1068 1.34.4.2 perseant summitfb_write4(sc, VISFX_FG_COLOUR, 0);
1069 1.34.4.2 perseant summitfb_write4(sc, VISFX_START, 0);
1070 1.34.4.2 perseant summitfb_write4(sc, VISFX_SIZE, (sc->sc_width << 16) | sc->sc_height);
1071 1.34.4.2 perseant }
1072 1.34.4.2 perseant
1073 1.34.4.2 perseant static void
1074 1.34.4.2 perseant summitfb_rectfill(struct summitfb_softc *sc, int x, int y, int wi, int he,
1075 1.34.4.2 perseant uint32_t bg)
1076 1.34.4.2 perseant {
1077 1.34.4.2 perseant
1078 1.34.4.2 perseant summitfb_write_mode(sc, VISFX_WRITE_MODE_FILL);
1079 1.34.4.2 perseant summitfb_wait_fifo(sc, 10);
1080 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, RopSrc);
1081 1.34.4.2 perseant summitfb_write4(sc, VISFX_FG_COLOUR, bg);
1082 1.34.4.2 perseant summitfb_write4(sc, VISFX_START, (x << 16) | y);
1083 1.34.4.2 perseant summitfb_write4(sc, VISFX_SIZE, (wi << 16) | he);
1084 1.34.4.2 perseant }
1085 1.34.4.2 perseant
1086 1.34.4.2 perseant static void
1087 1.34.4.2 perseant summitfb_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi,
1088 1.34.4.2 perseant int he, int rop)
1089 1.34.4.2 perseant {
1090 1.34.4.2 perseant struct summitfb_softc *sc = cookie;
1091 1.34.4.2 perseant uint32_t read_mode, write_mode;
1092 1.34.4.2 perseant
1093 1.34.4.2 perseant read_mode = OTC04 | BIN8I;
1094 1.34.4.2 perseant write_mode = OTC04 | BIN8I;
1095 1.34.4.2 perseant if (ys >= sc->sc_height) {
1096 1.34.4.2 perseant read_mode |= BUFBL;
1097 1.34.4.2 perseant ys -= sc->sc_height;
1098 1.34.4.2 perseant }
1099 1.34.4.2 perseant if (yd >= sc->sc_height) {
1100 1.34.4.2 perseant write_mode |= BUFBL;
1101 1.34.4.2 perseant yd -= sc->sc_height;
1102 1.34.4.2 perseant }
1103 1.34.4.2 perseant summitfb_write_mode(sc, write_mode);
1104 1.34.4.2 perseant summitfb_read_mode(sc, read_mode);
1105 1.34.4.2 perseant summitfb_wait_fifo(sc, 10);
1106 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, rop);
1107 1.34.4.2 perseant summitfb_write4(sc, VISFX_COPY_SRC, (xs << 16) | ys);
1108 1.34.4.2 perseant summitfb_write4(sc, VISFX_COPY_WH, (wi << 16) | he);
1109 1.34.4.2 perseant summitfb_write4(sc, VISFX_COPY_DST, (xd << 16) | yd);
1110 1.34.4.2 perseant
1111 1.34.4.2 perseant }
1112 1.34.4.2 perseant
1113 1.34.4.2 perseant static void
1114 1.34.4.2 perseant summitfb_nuke_cursor(struct rasops_info *ri)
1115 1.34.4.2 perseant {
1116 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1117 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1118 1.34.4.2 perseant int wi, he, x, y;
1119 1.34.4.2 perseant
1120 1.34.4.2 perseant if (ri->ri_flg & RI_CURSOR) {
1121 1.34.4.2 perseant wi = ri->ri_font->fontwidth;
1122 1.34.4.2 perseant he = ri->ri_font->fontheight;
1123 1.34.4.2 perseant x = ri->ri_ccol * wi + ri->ri_xorigin;
1124 1.34.4.2 perseant y = ri->ri_crow * he + ri->ri_yorigin;
1125 1.34.4.2 perseant summitfb_bitblt(sc, x, y, x, y, wi, he, RopInv);
1126 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1127 1.34.4.2 perseant }
1128 1.34.4.2 perseant }
1129 1.34.4.2 perseant
1130 1.34.4.2 perseant static void
1131 1.34.4.2 perseant summitfb_cursor(void *cookie, int on, int row, int col)
1132 1.34.4.2 perseant {
1133 1.34.4.2 perseant struct rasops_info *ri = cookie;
1134 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1135 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1136 1.34.4.2 perseant int x, y, wi, he;
1137 1.34.4.2 perseant
1138 1.34.4.2 perseant wi = ri->ri_font->fontwidth;
1139 1.34.4.2 perseant he = ri->ri_font->fontheight;
1140 1.34.4.2 perseant
1141 1.34.4.2 perseant if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1142 1.34.4.2 perseant if (on) {
1143 1.34.4.2 perseant if (ri->ri_flg & RI_CURSOR) {
1144 1.34.4.2 perseant summitfb_nuke_cursor(ri);
1145 1.34.4.2 perseant }
1146 1.34.4.2 perseant x = col * wi + ri->ri_xorigin;
1147 1.34.4.2 perseant y = row * he + ri->ri_yorigin;
1148 1.34.4.2 perseant summitfb_bitblt(sc, x, y, x, y, wi, he, RopInv);
1149 1.34.4.2 perseant ri->ri_flg |= RI_CURSOR;
1150 1.34.4.2 perseant }
1151 1.34.4.2 perseant ri->ri_crow = row;
1152 1.34.4.2 perseant ri->ri_ccol = col;
1153 1.34.4.2 perseant } else {
1154 1.34.4.2 perseant ri->ri_crow = row;
1155 1.34.4.2 perseant ri->ri_ccol = col;
1156 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1157 1.34.4.2 perseant }
1158 1.34.4.2 perseant
1159 1.34.4.2 perseant }
1160 1.34.4.2 perseant
1161 1.34.4.2 perseant static void
1162 1.34.4.2 perseant summitfb_putchar(void *cookie, int row, int col, u_int c, long attr)
1163 1.34.4.2 perseant {
1164 1.34.4.2 perseant struct rasops_info *ri = cookie;
1165 1.34.4.2 perseant struct wsdisplay_font *font = PICK_FONT(ri, c);
1166 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1167 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1168 1.34.4.2 perseant void *data;
1169 1.34.4.2 perseant int i, x, y, wi, he;
1170 1.34.4.2 perseant uint32_t bg, fg, mask;
1171 1.34.4.2 perseant
1172 1.34.4.2 perseant if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
1173 1.34.4.2 perseant return;
1174 1.34.4.2 perseant
1175 1.34.4.2 perseant if (!CHAR_IN_FONT(c, font))
1176 1.34.4.2 perseant return;
1177 1.34.4.2 perseant
1178 1.34.4.2 perseant if (row == ri->ri_crow && col == ri->ri_ccol) {
1179 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1180 1.34.4.2 perseant }
1181 1.34.4.2 perseant
1182 1.34.4.2 perseant wi = font->fontwidth;
1183 1.34.4.2 perseant he = font->fontheight;
1184 1.34.4.2 perseant
1185 1.34.4.2 perseant x = ri->ri_xorigin + col * wi;
1186 1.34.4.2 perseant y = ri->ri_yorigin + row * he;
1187 1.34.4.2 perseant
1188 1.34.4.2 perseant bg = ri->ri_devcmap[(attr >> 16) & 0xf];
1189 1.34.4.2 perseant
1190 1.34.4.2 perseant /* if we're drawing a space we're done here */
1191 1.34.4.2 perseant if (c == 0x20) {
1192 1.34.4.2 perseant summitfb_rectfill(sc, x, y, wi, he, bg);
1193 1.34.4.2 perseant return;
1194 1.34.4.2 perseant }
1195 1.34.4.2 perseant
1196 1.34.4.2 perseant fg = ri->ri_devcmap[(attr >> 24) & 0x0f];
1197 1.34.4.2 perseant
1198 1.34.4.2 perseant summitfb_write_mode(sc, VISFX_WRITE_MODE_EXPAND);
1199 1.34.4.2 perseant summitfb_wait_fifo(sc, 12);
1200 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO, RopSrc);
1201 1.34.4.2 perseant summitfb_write4(sc, VISFX_FG_COLOUR, fg);
1202 1.34.4.2 perseant summitfb_write4(sc, VISFX_BG_COLOUR, bg);
1203 1.34.4.2 perseant mask = 0xffffffff << (32 - wi);
1204 1.34.4.2 perseant summitfb_write4(sc, VISFX_PIXEL_MASK, mask);
1205 1.34.4.2 perseant /* not a tpyo, coordinates *are* backwards for this register */
1206 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_WRITE_DEST, (y << 16) | x);
1207 1.34.4.2 perseant
1208 1.34.4.2 perseant data = WSFONT_GLYPH(c, font);
1209 1.34.4.2 perseant
1210 1.34.4.2 perseant if (ri->ri_font->stride == 1) {
1211 1.34.4.2 perseant uint8_t *data8 = data;
1212 1.34.4.2 perseant for (i = 0; i < he; i++) {
1213 1.34.4.2 perseant mask = *data8;
1214 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRY,
1215 1.34.4.2 perseant mask << 24);
1216 1.34.4.2 perseant data8++;
1217 1.34.4.2 perseant }
1218 1.34.4.2 perseant } else {
1219 1.34.4.2 perseant uint16_t *data16 = data;
1220 1.34.4.2 perseant for (i = 0; i < he; i++) {
1221 1.34.4.2 perseant mask = *data16;
1222 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRY,
1223 1.34.4.2 perseant mask << 16);
1224 1.34.4.2 perseant data16++;
1225 1.34.4.2 perseant }
1226 1.34.4.2 perseant }
1227 1.34.4.2 perseant }
1228 1.34.4.2 perseant
1229 1.34.4.2 perseant static void
1230 1.34.4.2 perseant summitfb_putchar_aa(void *cookie, int row, int col, u_int c, long attr)
1231 1.34.4.2 perseant {
1232 1.34.4.2 perseant struct rasops_info *ri = cookie;
1233 1.34.4.2 perseant struct wsdisplay_font *font = PICK_FONT(ri, c);
1234 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1235 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1236 1.34.4.2 perseant int x, y, wi, he, rv = GC_NOPE, i, j;
1237 1.34.4.2 perseant uint32_t bg, fg, tmp;
1238 1.34.4.2 perseant uint8_t *data;
1239 1.34.4.2 perseant
1240 1.34.4.2 perseant if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
1241 1.34.4.2 perseant return;
1242 1.34.4.2 perseant
1243 1.34.4.2 perseant if (!CHAR_IN_FONT(c, font))
1244 1.34.4.2 perseant return;
1245 1.34.4.2 perseant
1246 1.34.4.2 perseant if (row == ri->ri_crow && col == ri->ri_ccol) {
1247 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1248 1.34.4.2 perseant }
1249 1.34.4.2 perseant
1250 1.34.4.2 perseant wi = font->fontwidth;
1251 1.34.4.2 perseant he = font->fontheight;
1252 1.34.4.2 perseant
1253 1.34.4.2 perseant x = ri->ri_xorigin + col * wi;
1254 1.34.4.2 perseant y = ri->ri_yorigin + row * he;
1255 1.34.4.2 perseant
1256 1.34.4.2 perseant bg = ri->ri_devcmap[(attr >> 16) & 0xf];
1257 1.34.4.2 perseant
1258 1.34.4.2 perseant if (c == 0x20) {
1259 1.34.4.2 perseant summitfb_rectfill(sc, x, y, wi, he, bg);
1260 1.34.4.2 perseant return;
1261 1.34.4.2 perseant }
1262 1.34.4.2 perseant
1263 1.34.4.2 perseant rv = glyphcache_try(&sc->sc_gc, c, x, y, attr);
1264 1.34.4.2 perseant if (rv == GC_OK)
1265 1.34.4.2 perseant return;
1266 1.34.4.2 perseant
1267 1.34.4.2 perseant /*
1268 1.34.4.2 perseant * first we clear the background - we should be able to use the CBR
1269 1.34.4.2 perseant * register as constant background but so far I couldn't make that work
1270 1.34.4.2 perseant */
1271 1.34.4.2 perseant summitfb_rectfill(sc, x, y, wi, he, bg);
1272 1.34.4.2 perseant
1273 1.34.4.2 perseant summitfb_write_mode(sc, OTC01 | BIN332F | BUFovl);
1274 1.34.4.2 perseant /* we need the foreground colour as full RGB8 */
1275 1.34.4.2 perseant fg = sc->sc_palette[(attr >> 24) & 0xf];
1276 1.34.4.2 perseant
1277 1.34.4.2 perseant /*
1278 1.34.4.2 perseant * set the blending equation to
1279 1.34.4.2 perseant * src_color * src_alpha + dst_color * (1 - src_alpha)
1280 1.34.4.2 perseant */
1281 1.34.4.2 perseant summitfb_write4(sc, VISFX_IBO,
1282 1.34.4.2 perseant IBO_ADD | SRC(IBO_SRC) | DST(IBO_ONE_MINUS_SRC));
1283 1.34.4.2 perseant
1284 1.34.4.2 perseant /* get the glyph */
1285 1.34.4.2 perseant data = WSFONT_GLYPH(c, font);
1286 1.34.4.2 perseant for (i = 0; i < he; i++) {
1287 1.34.4.2 perseant /*
1288 1.34.4.2 perseant * make some room in the pipeline
1289 1.34.4.2 perseant * with just plain ROPs we can just hammer the FIFO without
1290 1.34.4.2 perseant * having to worry about overflowing it but I suspect with
1291 1.34.4.2 perseant * alpha blending enabled things may be a little slower
1292 1.34.4.2 perseant */
1293 1.34.4.2 perseant summitfb_wait_fifo(sc, wi * 2);
1294 1.34.4.2 perseant /* start a new line */
1295 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_WRITE_DEST, ((y + i) << 16) | x);
1296 1.34.4.2 perseant for (j = 0; j < wi; j++) {
1297 1.34.4.2 perseant tmp = *data;
1298 1.34.4.2 perseant /* alpha & RGB -> ARGB */
1299 1.34.4.2 perseant summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRX,
1300 1.34.4.2 perseant (tmp << 24) | fg);
1301 1.34.4.2 perseant data++;
1302 1.34.4.2 perseant }
1303 1.34.4.2 perseant }
1304 1.34.4.2 perseant
1305 1.34.4.2 perseant if (rv == GC_ADD)
1306 1.34.4.2 perseant glyphcache_add(&sc->sc_gc, c, x, y);
1307 1.34.4.2 perseant }
1308 1.34.4.2 perseant
1309 1.34.4.2 perseant static void
1310 1.34.4.2 perseant summitfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
1311 1.34.4.2 perseant {
1312 1.34.4.2 perseant struct rasops_info *ri = cookie;
1313 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1314 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1315 1.34.4.2 perseant int32_t xs, xd, y, width, height;
1316 1.34.4.2 perseant
1317 1.34.4.2 perseant if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1318 1.34.4.2 perseant
1319 1.34.4.2 perseant if (ri->ri_crow == row &&
1320 1.34.4.2 perseant ri->ri_ccol >= srccol && ri->ri_ccol < (srccol + ncols) &&
1321 1.34.4.2 perseant (ri->ri_flg & RI_CURSOR)) {
1322 1.34.4.2 perseant summitfb_nuke_cursor(ri);
1323 1.34.4.2 perseant }
1324 1.34.4.2 perseant
1325 1.34.4.2 perseant xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
1326 1.34.4.2 perseant xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
1327 1.34.4.2 perseant y = ri->ri_yorigin + ri->ri_font->fontheight * row;
1328 1.34.4.2 perseant width = ri->ri_font->fontwidth * ncols;
1329 1.34.4.2 perseant height = ri->ri_font->fontheight;
1330 1.34.4.2 perseant summitfb_bitblt(sc, xs, y, xd, y, width, height, RopSrc);
1331 1.34.4.2 perseant
1332 1.34.4.2 perseant if (ri->ri_crow == row &&
1333 1.34.4.2 perseant ri->ri_ccol >= dstcol && ri->ri_ccol < (dstcol + ncols))
1334 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1335 1.34.4.2 perseant }
1336 1.34.4.2 perseant }
1337 1.34.4.2 perseant
1338 1.34.4.2 perseant static void
1339 1.34.4.2 perseant summitfb_erasecols(void *cookie, int row, int startcol, int ncols,
1340 1.34.4.2 perseant long fillattr)
1341 1.34.4.2 perseant {
1342 1.34.4.2 perseant struct rasops_info *ri = cookie;
1343 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1344 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1345 1.34.4.2 perseant int32_t x, y, width, height, fg, bg, ul;
1346 1.34.4.2 perseant
1347 1.34.4.2 perseant if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1348 1.34.4.2 perseant x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
1349 1.34.4.2 perseant y = ri->ri_yorigin + ri->ri_font->fontheight * row;
1350 1.34.4.2 perseant width = ri->ri_font->fontwidth * ncols;
1351 1.34.4.2 perseant height = ri->ri_font->fontheight;
1352 1.34.4.2 perseant rasops_unpack_attr(fillattr, &fg, &bg, &ul);
1353 1.34.4.2 perseant
1354 1.34.4.2 perseant summitfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
1355 1.34.4.2 perseant
1356 1.34.4.2 perseant if (ri->ri_crow == row &&
1357 1.34.4.2 perseant ri->ri_ccol >= startcol &&
1358 1.34.4.2 perseant ri->ri_ccol < (startcol + ncols))
1359 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1360 1.34.4.2 perseant }
1361 1.34.4.2 perseant }
1362 1.34.4.2 perseant
1363 1.34.4.2 perseant static void
1364 1.34.4.2 perseant summitfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
1365 1.34.4.2 perseant {
1366 1.34.4.2 perseant struct rasops_info *ri = cookie;
1367 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1368 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1369 1.34.4.2 perseant int32_t x, ys, yd, width, height;
1370 1.34.4.2 perseant
1371 1.34.4.2 perseant if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1372 1.34.4.2 perseant
1373 1.34.4.2 perseant if (ri->ri_crow >= srcrow && ri->ri_crow < (srcrow + nrows) &&
1374 1.34.4.2 perseant (ri->ri_flg & RI_CURSOR)) {
1375 1.34.4.2 perseant summitfb_nuke_cursor(ri);
1376 1.34.4.2 perseant }
1377 1.34.4.2 perseant
1378 1.34.4.2 perseant x = ri->ri_xorigin;
1379 1.34.4.2 perseant ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
1380 1.34.4.2 perseant yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
1381 1.34.4.2 perseant width = ri->ri_emuwidth;
1382 1.34.4.2 perseant height = ri->ri_font->fontheight * nrows;
1383 1.34.4.2 perseant summitfb_bitblt(sc, x, ys, x, yd, width, height, RopSrc);
1384 1.34.4.2 perseant
1385 1.34.4.2 perseant if (ri->ri_crow >= dstrow && ri->ri_crow < (dstrow + nrows))
1386 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1387 1.34.4.2 perseant }
1388 1.34.4.2 perseant }
1389 1.34.4.2 perseant
1390 1.34.4.2 perseant static void
1391 1.34.4.2 perseant summitfb_eraserows(void *cookie, int row, int nrows, long fillattr)
1392 1.34.4.2 perseant {
1393 1.34.4.2 perseant struct rasops_info *ri = cookie;
1394 1.34.4.2 perseant struct vcons_screen *scr = ri->ri_hw;
1395 1.34.4.2 perseant struct summitfb_softc *sc = scr->scr_cookie;
1396 1.34.4.2 perseant int32_t x, y, width, height, fg, bg, ul;
1397 1.34.4.2 perseant
1398 1.34.4.2 perseant if (sc->sc_locked == 0 && sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1399 1.34.4.2 perseant x = ri->ri_xorigin;
1400 1.34.4.2 perseant y = ri->ri_yorigin + ri->ri_font->fontheight * row;
1401 1.34.4.2 perseant width = ri->ri_emuwidth;
1402 1.34.4.2 perseant height = ri->ri_font->fontheight * nrows;
1403 1.34.4.2 perseant rasops_unpack_attr(fillattr, &fg, &bg, &ul);
1404 1.34.4.2 perseant
1405 1.34.4.2 perseant summitfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
1406 1.34.4.2 perseant
1407 1.34.4.2 perseant if (ri->ri_crow >= row && ri->ri_crow < (row + nrows))
1408 1.34.4.2 perseant ri->ri_flg &= ~RI_CURSOR;
1409 1.34.4.2 perseant }
1410 1.34.4.2 perseant }
1411 1.34.4.2 perseant
1412 1.34.4.2 perseant static void
1413 1.34.4.2 perseant summitfb_move_cursor(struct summitfb_softc *sc, int x, int y)
1414 1.34.4.2 perseant {
1415 1.34.4.2 perseant uint32_t pos;
1416 1.34.4.2 perseant
1417 1.34.4.2 perseant sc->sc_cursor_x = x;
1418 1.34.4.2 perseant x -= sc->sc_hot_x;
1419 1.34.4.2 perseant sc->sc_cursor_y = y;
1420 1.34.4.2 perseant y -= sc->sc_hot_y;
1421 1.34.4.2 perseant
1422 1.34.4.2 perseant if (x < 0)
1423 1.34.4.2 perseant x = 0x1000 - x;
1424 1.34.4.2 perseant if (y < 0)
1425 1.34.4.2 perseant y = 0x1000 - y;
1426 1.34.4.2 perseant pos = (x << 16) | y;
1427 1.34.4.2 perseant if (sc->sc_enabled)
1428 1.34.4.2 perseant pos |= 0x80000000;
1429 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_POS, pos);
1430 1.34.4.2 perseant }
1431 1.34.4.2 perseant
1432 1.34.4.2 perseant static int
1433 1.34.4.2 perseant summitfb_do_cursor(struct summitfb_softc *sc, struct wsdisplay_cursor *cur)
1434 1.34.4.2 perseant {
1435 1.34.4.2 perseant
1436 1.34.4.2 perseant if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
1437 1.34.4.2 perseant sc->sc_enabled = cur->enable;
1438 1.34.4.2 perseant cur->which |= WSDISPLAY_CURSOR_DOPOS;
1439 1.34.4.2 perseant }
1440 1.34.4.2 perseant if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
1441 1.34.4.2 perseant sc->sc_hot_x = cur->hot.x;
1442 1.34.4.2 perseant sc->sc_hot_y = cur->hot.y;
1443 1.34.4.2 perseant cur->which |= WSDISPLAY_CURSOR_DOPOS;
1444 1.34.4.2 perseant }
1445 1.34.4.2 perseant if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
1446 1.34.4.2 perseant summitfb_move_cursor(sc, cur->pos.x, cur->pos.y);
1447 1.34.4.2 perseant }
1448 1.34.4.2 perseant if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
1449 1.34.4.2 perseant uint32_t rgb;
1450 1.34.4.2 perseant uint8_t r[2], g[2], b[2];
1451 1.34.4.2 perseant
1452 1.34.4.2 perseant copyin(cur->cmap.blue, b, 2);
1453 1.34.4.2 perseant copyin(cur->cmap.green, g, 2);
1454 1.34.4.2 perseant copyin(cur->cmap.red, r, 2);
1455 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_INDEX, 0);
1456 1.34.4.2 perseant rgb = r[0] << 16 | g[0] << 8 | b[0];
1457 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_BG, rgb);
1458 1.34.4.2 perseant rgb = r[1] << 16 | g[1] << 8 | b[1];
1459 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_FG, rgb);
1460 1.34.4.2 perseant
1461 1.34.4.2 perseant }
1462 1.34.4.2 perseant if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
1463 1.34.4.2 perseant
1464 1.34.4.2 perseant uint32_t buffer[128], latch, tmp;
1465 1.34.4.2 perseant int i;
1466 1.34.4.2 perseant
1467 1.34.4.2 perseant copyin(cur->mask, buffer, 512);
1468 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_INDEX, 0);
1469 1.34.4.2 perseant for (i = 0; i < 128; i += 2) {
1470 1.34.4.2 perseant latch = 0;
1471 1.34.4.2 perseant tmp = buffer[i] & 0x80808080;
1472 1.34.4.2 perseant latch |= tmp >> 7;
1473 1.34.4.2 perseant tmp = buffer[i] & 0x40404040;
1474 1.34.4.2 perseant latch |= tmp >> 5;
1475 1.34.4.2 perseant tmp = buffer[i] & 0x20202020;
1476 1.34.4.2 perseant latch |= tmp >> 3;
1477 1.34.4.2 perseant tmp = buffer[i] & 0x10101010;
1478 1.34.4.2 perseant latch |= tmp >> 1;
1479 1.34.4.2 perseant tmp = buffer[i] & 0x08080808;
1480 1.34.4.2 perseant latch |= tmp << 1;
1481 1.34.4.2 perseant tmp = buffer[i] & 0x04040404;
1482 1.34.4.2 perseant latch |= tmp << 3;
1483 1.34.4.2 perseant tmp = buffer[i] & 0x02020202;
1484 1.34.4.2 perseant latch |= tmp << 5;
1485 1.34.4.2 perseant tmp = buffer[i] & 0x01010101;
1486 1.34.4.2 perseant latch |= tmp << 7;
1487 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_DATA, latch);
1488 1.34.4.2 perseant latch = 0;
1489 1.34.4.2 perseant tmp = buffer[i + 1] & 0x80808080;
1490 1.34.4.2 perseant latch |= tmp >> 7;
1491 1.34.4.2 perseant tmp = buffer[i + 1] & 0x40404040;
1492 1.34.4.2 perseant latch |= tmp >> 5;
1493 1.34.4.2 perseant tmp = buffer[i + 1] & 0x20202020;
1494 1.34.4.2 perseant latch |= tmp >> 3;
1495 1.34.4.2 perseant tmp = buffer[i + 1] & 0x10101010;
1496 1.34.4.2 perseant latch |= tmp >> 1;
1497 1.34.4.2 perseant tmp = buffer[i + 1] & 0x08080808;
1498 1.34.4.2 perseant latch |= tmp << 1;
1499 1.34.4.2 perseant tmp = buffer[i + 1] & 0x04040404;
1500 1.34.4.2 perseant latch |= tmp << 3;
1501 1.34.4.2 perseant tmp = buffer[i + 1] & 0x02020202;
1502 1.34.4.2 perseant latch |= tmp << 5;
1503 1.34.4.2 perseant tmp = buffer[i + 1] & 0x01010101;
1504 1.34.4.2 perseant latch |= tmp << 7;
1505 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_DATA, latch);
1506 1.34.4.2 perseant }
1507 1.34.4.2 perseant
1508 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_INDEX, 0x80);
1509 1.34.4.2 perseant copyin(cur->image, buffer, 512);
1510 1.34.4.2 perseant for (i = 0; i < 128; i += 2) {
1511 1.34.4.2 perseant latch = 0;
1512 1.34.4.2 perseant tmp = buffer[i] & 0x80808080;
1513 1.34.4.2 perseant latch |= tmp >> 7;
1514 1.34.4.2 perseant tmp = buffer[i] & 0x40404040;
1515 1.34.4.2 perseant latch |= tmp >> 5;
1516 1.34.4.2 perseant tmp = buffer[i] & 0x20202020;
1517 1.34.4.2 perseant latch |= tmp >> 3;
1518 1.34.4.2 perseant tmp = buffer[i] & 0x10101010;
1519 1.34.4.2 perseant latch |= tmp >> 1;
1520 1.34.4.2 perseant tmp = buffer[i] & 0x08080808;
1521 1.34.4.2 perseant latch |= tmp << 1;
1522 1.34.4.2 perseant tmp = buffer[i] & 0x04040404;
1523 1.34.4.2 perseant latch |= tmp << 3;
1524 1.34.4.2 perseant tmp = buffer[i] & 0x02020202;
1525 1.34.4.2 perseant latch |= tmp << 5;
1526 1.34.4.2 perseant tmp = buffer[i] & 0x01010101;
1527 1.34.4.2 perseant latch |= tmp << 7;
1528 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_DATA, latch);
1529 1.34.4.2 perseant latch = 0;
1530 1.34.4.2 perseant tmp = buffer[i + 1] & 0x80808080;
1531 1.34.4.2 perseant latch |= tmp >> 7;
1532 1.34.4.2 perseant tmp = buffer[i + 1] & 0x40404040;
1533 1.34.4.2 perseant latch |= tmp >> 5;
1534 1.34.4.2 perseant tmp = buffer[i + 1] & 0x20202020;
1535 1.34.4.2 perseant latch |= tmp >> 3;
1536 1.34.4.2 perseant tmp = buffer[i + 1] & 0x10101010;
1537 1.34.4.2 perseant latch |= tmp >> 1;
1538 1.34.4.2 perseant tmp = buffer[i + 1] & 0x08080808;
1539 1.34.4.2 perseant latch |= tmp << 1;
1540 1.34.4.2 perseant tmp = buffer[i + 1] & 0x04040404;
1541 1.34.4.2 perseant latch |= tmp << 3;
1542 1.34.4.2 perseant tmp = buffer[i + 1] & 0x02020202;
1543 1.34.4.2 perseant latch |= tmp << 5;
1544 1.34.4.2 perseant tmp = buffer[i + 1] & 0x01010101;
1545 1.34.4.2 perseant latch |= tmp << 7;
1546 1.34.4.2 perseant summitfb_write4(sc, VISFX_CURSOR_DATA, latch);
1547 1.34.4.2 perseant }
1548 1.34.4.2 perseant }
1549 1.34.4.2 perseant
1550 1.34.4.2 perseant return 0;
1551 1.34.4.2 perseant }
1552 1.34.4.2 perseant
1553 1.34.4.2 perseant static void
1554 1.34.4.2 perseant summitfb_set_video(struct summitfb_softc *sc, int on)
1555 1.34.4.2 perseant {
1556 1.34.4.2 perseant
1557 1.34.4.2 perseant if (sc->sc_video_on == on)
1558 1.34.4.2 perseant return;
1559 1.34.4.2 perseant
1560 1.34.4.2 perseant sc->sc_video_on = on;
1561 1.34.4.2 perseant
1562 1.34.4.2 perseant summitfb_wait(sc);
1563 1.34.4.2 perseant if (on) {
1564 1.34.4.2 perseant summitfb_write4(sc, VISFX_MPC, MPC_VIDEO_ON);
1565 1.34.4.2 perseant } else {
1566 1.34.4.2 perseant summitfb_write4(sc, VISFX_MPC, MPC_VSYNC_OFF | MPC_HSYNC_OFF);
1567 1.34.4.2 perseant }
1568 1.34.4.2 perseant }
1569 1.34.4.2 perseant
1570 1.34.4.2 perseant static void
1571 1.34.4.2 perseant summitfb_copyfont(struct summitfb_softc *sc)
1572 1.34.4.2 perseant {
1573 1.34.4.2 perseant struct sti_font *fp = &sc->sc_scr.scr_curfont;
1574 1.34.4.2 perseant uint8_t *font = sc->sc_scr.scr_romfont;
1575 1.34.4.2 perseant uint8_t *fontbuf, *fontdata, *src, *dst;
1576 1.34.4.2 perseant struct wsdisplay_font *f;
1577 1.34.4.2 perseant int bufsize, i, si;
1578 1.34.4.2 perseant
1579 1.34.4.2 perseant if (font == NULL)
1580 1.34.4.2 perseant return;
1581 1.34.4.2 perseant
1582 1.34.4.2 perseant bufsize = sizeof(struct wsdisplay_font) + 32 + fp->bpc * (fp->last - fp->first);
1583 1.34.4.2 perseant DPRINTF(("%s: %dx%d %d\n", __func__, fp->width, fp->height, bufsize));
1584 1.34.4.2 perseant fontbuf = kmem_alloc(bufsize, KM_SLEEP);
1585 1.34.4.2 perseant f = (struct wsdisplay_font *)fontbuf;
1586 1.34.4.2 perseant f->name = fontbuf + sizeof(struct wsdisplay_font);
1587 1.34.4.2 perseant fontdata = fontbuf + sizeof(struct wsdisplay_font) + 32;
1588 1.34.4.2 perseant strcpy(fontbuf + sizeof(struct wsdisplay_font), "HP ROM");
1589 1.34.4.2 perseant f->firstchar = fp->first;
1590 1.34.4.2 perseant f->numchars = (fp->last + 1) - fp->first;
1591 1.34.4.2 perseant f->encoding = WSDISPLAY_FONTENC_ISO;
1592 1.34.4.2 perseant f->fontwidth = fp->width;
1593 1.34.4.2 perseant f->fontheight = fp->height;
1594 1.34.4.2 perseant f->stride = (fp->width + 7) >> 3;
1595 1.34.4.2 perseant f->bitorder = WSDISPLAY_FONTORDER_L2R;
1596 1.34.4.2 perseant f->byteorder = WSDISPLAY_FONTORDER_L2R;
1597 1.34.4.2 perseant f->data = fontdata;
1598 1.34.4.2 perseant /* skip over font struct */
1599 1.34.4.2 perseant font += sizeof(struct sti_font);
1600 1.34.4.2 perseant /* now copy and rearrange the glyphs into ISO order */
1601 1.34.4.2 perseant /* first, copy the characters up to 0x7f */
1602 1.34.4.2 perseant memcpy(fontdata, font, (0x80 - fp->first) * fp->bpc);
1603 1.34.4.2 perseant /* zero 0x80 to 0x9f */
1604 1.34.4.2 perseant memset(fontdata + 0x80 * fp->bpc, 0, 0x20 * fp->bpc);
1605 1.34.4.2 perseant /* rearrange 0xa0 till last */
1606 1.34.4.2 perseant for (i = 0xa0; i < (fp->last + 1); i++) {
1607 1.34.4.2 perseant dst = fontdata + fp->bpc * i;
1608 1.34.4.2 perseant si = sti_unitoroman[i - 0xa0];
1609 1.34.4.2 perseant if (si != 0) {
1610 1.34.4.2 perseant src = font + fp->bpc * si;
1611 1.34.4.2 perseant memcpy(dst, src, fp->bpc);
1612 1.34.4.2 perseant } else {
1613 1.34.4.2 perseant /* no mapping - zero this cell */
1614 1.34.4.2 perseant memset(dst, 0, fp->bpc);
1615 1.34.4.2 perseant }
1616 1.34.4.2 perseant }
1617 1.34.4.2 perseant wsfont_add(f, 0);
1618 1.34.4.2 perseant }
1619