| @@ -1,1650 +1,1648 @@ | | | @@ -1,1650 +1,1648 @@ |
1 | /* $NetBSD: sti.c,v 1.28 2021/03/07 14:31:20 skrll Exp $ */ | | 1 | /* $NetBSD: sti.c,v 1.29 2021/03/14 08:13:58 skrll Exp $ */ |
2 | | | 2 | |
3 | /* $OpenBSD: sti.c,v 1.61 2009/09/05 14:09:35 miod Exp $ */ | | 3 | /* $OpenBSD: sti.c,v 1.61 2009/09/05 14:09:35 miod Exp $ */ |
4 | | | 4 | |
5 | /* | | 5 | /* |
6 | * Copyright (c) 2000-2003 Michael Shalayeff | | 6 | * Copyright (c) 2000-2003 Michael Shalayeff |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the | | 15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. | | 16 | * documentation and/or other materials provided with the distribution. |
17 | * | | 17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
21 | * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, | | 21 | * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, |
22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | | 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | | 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
24 | * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 24 | * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | | 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | | 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
27 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | 27 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
28 | * THE POSSIBILITY OF SUCH DAMAGE. | | 28 | * THE POSSIBILITY OF SUCH DAMAGE. |
29 | */ | | 29 | */ |
30 | /* | | 30 | /* |
31 | * TODO: | | 31 | * TODO: |
32 | * call sti procs asynchronously; | | 32 | * call sti procs asynchronously; |
33 | * implement console scroll-back; | | 33 | * implement console scroll-back; |
34 | * X11 support on more models. | | 34 | * X11 support on more models. |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.28 2021/03/07 14:31:20 skrll Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.29 2021/03/14 08:13:58 skrll Exp $"); |
39 | | | 39 | |
40 | #include "wsdisplay.h" | | 40 | #include "wsdisplay.h" |
41 | | | 41 | |
42 | #include <sys/param.h> | | 42 | #include <sys/param.h> |
43 | #include <sys/systm.h> | | 43 | #include <sys/systm.h> |
44 | #include <sys/device.h> | | 44 | #include <sys/device.h> |
45 | #include <sys/malloc.h> | | 45 | #include <sys/malloc.h> |
46 | | | 46 | |
47 | #include <uvm/uvm_extern.h> | | 47 | #include <uvm/uvm_extern.h> |
48 | | | 48 | |
49 | #include <sys/bus.h> | | 49 | #include <sys/bus.h> |
50 | | | 50 | |
51 | #include <dev/wscons/wsdisplayvar.h> | | 51 | #include <dev/wscons/wsdisplayvar.h> |
52 | #include <dev/wscons/wsconsio.h> | | 52 | #include <dev/wscons/wsconsio.h> |
53 | | | 53 | |
54 | #include <dev/ic/stireg.h> | | 54 | #include <dev/ic/stireg.h> |
55 | #include <dev/ic/stivar.h> | | 55 | #include <dev/ic/stivar.h> |
56 | | | 56 | |
57 | #ifdef STIDEBUG | | 57 | #ifdef STIDEBUG |
58 | | | 58 | |
59 | #define DPRINTF(s) do { \ | | 59 | #define DPRINTF(s) do { \ |
60 | if (stidebug) \ | | 60 | if (stidebug) \ |
61 | printf s; \ | | 61 | printf s; \ |
62 | } while(0) | | 62 | } while(0) |
63 | | | 63 | |
64 | int stidebug = 1; | | 64 | int stidebug = 1; |
65 | #else | | 65 | #else |
66 | #define DPRINTF(s) /* */ | | 66 | #define DPRINTF(s) /* */ |
67 | #endif | | 67 | #endif |
68 | | | 68 | |
69 | void sti_cursor(void *, int, int, int); | | 69 | void sti_cursor(void *, int, int, int); |
70 | int sti_mapchar(void *, int, u_int *); | | 70 | int sti_mapchar(void *, int, u_int *); |
71 | void sti_putchar(void *, int, int, u_int, long); | | 71 | void sti_putchar(void *, int, int, u_int, long); |
72 | void sti_copycols(void *, int, int, int, int); | | 72 | void sti_copycols(void *, int, int, int, int); |
73 | void sti_erasecols(void *, int, int, int, long); | | 73 | void sti_erasecols(void *, int, int, int, long); |
74 | void sti_copyrows(void *, int, int, int); | | 74 | void sti_copyrows(void *, int, int, int); |
75 | void sti_eraserows(void *, int, int, long); | | 75 | void sti_eraserows(void *, int, int, long); |
76 | int sti_alloc_attr(void *, int, int, int, long *); | | 76 | int sti_alloc_attr(void *, int, int, int, long *); |
77 | | | 77 | |
78 | /* pseudo attribute ops for sti ROM putchar function */ | | 78 | /* pseudo attribute ops for sti ROM putchar function */ |
79 | #define WSATTR_FG_SHIFT 24 | | 79 | #define WSATTR_FG_SHIFT 24 |
80 | #define WSATTR_BG_SHIFT 16 | | 80 | #define WSATTR_BG_SHIFT 16 |
81 | #define WSATTR_UNPACK_FG(attr) (((attr) >> WSATTR_FG_SHIFT) & 0xff) | | 81 | #define WSATTR_UNPACK_FG(attr) (((attr) >> WSATTR_FG_SHIFT) & 0xff) |
82 | #define WSATTR_UNPACK_BG(attr) (((attr) >> WSATTR_BG_SHIFT) & 0xff) | | 82 | #define WSATTR_UNPACK_BG(attr) (((attr) >> WSATTR_BG_SHIFT) & 0xff) |
83 | #define WSATTR_UNPACK_FLAG(attr) ((attr) & WSATTR_USERMASK) | | 83 | #define WSATTR_UNPACK_FLAG(attr) ((attr) & WSATTR_USERMASK) |
84 | #define WSATTR_PACK_FG(fg) ((fg) << WSATTR_FG_SHIFT) | | 84 | #define WSATTR_PACK_FG(fg) ((fg) << WSATTR_FG_SHIFT) |
85 | #define WSATTR_PACK_BG(bg) ((bg) << WSATTR_BG_SHIFT) | | 85 | #define WSATTR_PACK_BG(bg) ((bg) << WSATTR_BG_SHIFT) |
86 | #define WSATTR_PACK_FLAG(flag) ((flag)) | | 86 | #define WSATTR_PACK_FLAG(flag) ((flag)) |
87 | #define WSATTR_PACK(fg, bg, flag) \ | | 87 | #define WSATTR_PACK(fg, bg, flag) \ |
88 | (WSATTR_PACK_FG(fg) | WSATTR_PACK_BG(bg) | WSATTR_PACK_FLAG(flag)) | | 88 | (WSATTR_PACK_FG(fg) | WSATTR_PACK_BG(bg) | WSATTR_PACK_FLAG(flag)) |
89 | | | 89 | |
90 | struct wsdisplay_emulops sti_emulops = { | | 90 | struct wsdisplay_emulops sti_emulops = { |
91 | .cursor = sti_cursor, | | 91 | .cursor = sti_cursor, |
92 | .mapchar = sti_mapchar, | | 92 | .mapchar = sti_mapchar, |
93 | .putchar = sti_putchar, | | 93 | .putchar = sti_putchar, |
94 | .copycols = sti_copycols, | | 94 | .copycols = sti_copycols, |
95 | .erasecols = sti_erasecols, | | 95 | .erasecols = sti_erasecols, |
96 | .copyrows = sti_copyrows, | | 96 | .copyrows = sti_copyrows, |
97 | .eraserows = sti_eraserows, | | 97 | .eraserows = sti_eraserows, |
98 | .allocattr = sti_alloc_attr | | 98 | .allocattr = sti_alloc_attr |
99 | }; | | 99 | }; |
100 | | | 100 | |
101 | const struct wsdisplay_accessops sti_accessops = { | | 101 | const struct wsdisplay_accessops sti_accessops = { |
102 | .ioctl = sti_ioctl, | | 102 | .ioctl = sti_ioctl, |
103 | .mmap = sti_mmap, | | 103 | .mmap = sti_mmap, |
104 | .alloc_screen = sti_alloc_screen, | | 104 | .alloc_screen = sti_alloc_screen, |
105 | .free_screen = sti_free_screen, | | 105 | .free_screen = sti_free_screen, |
106 | .show_screen = sti_show_screen, | | 106 | .show_screen = sti_show_screen, |
107 | .load_font = sti_load_font | | 107 | .load_font = sti_load_font |
108 | }; | | 108 | }; |
109 | | | 109 | |
110 | enum sti_bmove_funcs { | | 110 | enum sti_bmove_funcs { |
111 | bmf_clear, bmf_copy, bmf_invert, bmf_underline | | 111 | bmf_clear, bmf_copy, bmf_invert, bmf_underline |
112 | }; | | 112 | }; |
113 | | | 113 | |
114 | void sti_bmove(struct sti_screen *, int, int, int, int, int, int, | | 114 | void sti_bmove(struct sti_screen *, int, int, int, int, int, int, |
115 | enum sti_bmove_funcs); | | 115 | enum sti_bmove_funcs); |
116 | int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); | | 116 | int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); |
117 | int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); | | 117 | int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); |
118 | | | 118 | |
119 | struct sti_screen *sti_attach_screen(struct sti_softc *, int); | | 119 | struct sti_screen *sti_attach_screen(struct sti_softc *, int); |
120 | void sti_describe_screen(struct sti_softc *, struct sti_screen *); | | 120 | void sti_describe_screen(struct sti_softc *, struct sti_screen *); |
121 | | | 121 | |
122 | int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, uint32_t, | | 122 | int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, uint32_t, |
123 | u_int); | | 123 | u_int); |
124 | void sti_region_setup(struct sti_screen *); | | 124 | void sti_region_setup(struct sti_screen *); |
125 | int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, | | 125 | int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, |
126 | bus_space_handle_t, bus_addr_t *, u_int); | | 126 | bus_space_handle_t, bus_addr_t *, u_int); |
127 | int sti_screen_setup(struct sti_screen *, int); | | 127 | int sti_screen_setup(struct sti_screen *, int); |
128 | | | 128 | |
129 | int ngle_default_putcmap(struct sti_screen *, u_int, u_int); | | 129 | int ngle_default_putcmap(struct sti_screen *, u_int, u_int); |
130 | | | 130 | |
131 | #ifndef SMALL_KERNEL | | 131 | #ifndef SMALL_KERNEL |
132 | void ngle_artist_setupfb(struct sti_screen *); | | 132 | void ngle_artist_setupfb(struct sti_screen *); |
133 | void ngle_elk_setupfb(struct sti_screen *); | | 133 | void ngle_elk_setupfb(struct sti_screen *); |
134 | void ngle_timber_setupfb(struct sti_screen *); | | 134 | void ngle_timber_setupfb(struct sti_screen *); |
135 | int ngle_putcmap(struct sti_screen *, u_int, u_int); | | 135 | int ngle_putcmap(struct sti_screen *, u_int, u_int); |
136 | #endif | | 136 | #endif |
137 | | | 137 | |
138 | #define STI_ENABLE_ROM(sc) \ | | 138 | #define STI_ENABLE_ROM(sc) \ |
139 | do { \ | | 139 | do { \ |
140 | if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \ | | 140 | if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \ |
141 | (*(sc)->sc_enable_rom)(sc); \ | | 141 | (*(sc)->sc_enable_rom)(sc); \ |
142 | } while (0) | | 142 | } while (0) |
143 | #define STI_DISABLE_ROM(sc) \ | | 143 | #define STI_DISABLE_ROM(sc) \ |
144 | do { \ | | 144 | do { \ |
145 | if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \ | | 145 | if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \ |
146 | (*(sc)->sc_disable_rom)(sc); \ | | 146 | (*(sc)->sc_disable_rom)(sc); \ |
147 | } while (0) | | 147 | } while (0) |
148 | | | 148 | |
149 | /* Macros to read larger than 8 bit values from byte roms */ | | 149 | /* Macros to read larger than 8 bit values from byte roms */ |
150 | #define parseshort(o) \ | | 150 | #define parseshort(o) \ |
151 | ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ | | 151 | ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ |
152 | (bus_space_read_1(memt, romh, (o) + 7))) | | 152 | (bus_space_read_1(memt, romh, (o) + 7))) |
153 | #define parseword(o) \ | | 153 | #define parseword(o) \ |
154 | ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ | | 154 | ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ |
155 | (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ | | 155 | (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ |
156 | (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ | | 156 | (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ |
157 | (bus_space_read_1(memt, romh, (o) + 15))) | | 157 | (bus_space_read_1(memt, romh, (o) + 15))) |
158 | | | 158 | |
159 | int | | 159 | int |
160 | sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot, | | 160 | sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot, |
161 | bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase) | | 161 | bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase) |
162 | { | | 162 | { |
163 | struct sti_rom *rom; | | 163 | struct sti_rom *rom; |
164 | int rc; | | 164 | int rc; |
165 | | | 165 | |
166 | rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF, | | 166 | rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF, |
167 | M_WAITOK | M_ZERO); | | 167 | M_WAITOK | M_ZERO); |
168 | rom->rom_softc = sc; | | 168 | rom->rom_softc = sc; |
169 | rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase); | | 169 | rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase); |
170 | if (rc != 0) { | | 170 | if (rc != 0) { |
171 | free(rom, M_DEVBUF); | | 171 | free(rom, M_DEVBUF); |
172 | return rc; | | 172 | return rc; |
173 | } | | 173 | } |
174 | | | 174 | |
175 | sc->sc_rom = rom; | | 175 | sc->sc_rom = rom; |
176 | | | 176 | |
177 | sti_describe(sc); | | 177 | sti_describe(sc); |
178 | | | 178 | |
179 | sc->sc_scr = sti_attach_screen(sc, | | 179 | sc->sc_scr = sti_attach_screen(sc, |
180 | sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR); | | 180 | sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR); |
181 | if (sc->sc_scr == NULL) | | 181 | if (sc->sc_scr == NULL) |
182 | rc = ENOMEM; | | 182 | rc = ENOMEM; |
183 | | | 183 | |
184 | return rc; | | 184 | return rc; |
185 | } | | 185 | } |
186 | | | 186 | |
187 | struct sti_screen * | | 187 | struct sti_screen * |
188 | sti_attach_screen(struct sti_softc *sc, int flags) | | 188 | sti_attach_screen(struct sti_softc *sc, int flags) |
189 | { | | 189 | { |
190 | struct sti_screen *scr; | | 190 | struct sti_screen *scr; |
191 | int rc; | | 191 | int rc; |
192 | | | 192 | |
193 | scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF, | | 193 | scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF, |
194 | M_WAITOK | M_ZERO); | | 194 | M_WAITOK | M_ZERO); |
195 | scr->scr_rom = sc->sc_rom; | | 195 | scr->scr_rom = sc->sc_rom; |
196 | rc = sti_screen_setup(scr, flags); | | 196 | rc = sti_screen_setup(scr, flags); |
197 | if (rc != 0) { | | 197 | if (rc != 0) { |
198 | free(scr, M_DEVBUF); | | 198 | free(scr, M_DEVBUF); |
199 | return NULL; | | 199 | return NULL; |
200 | } | | 200 | } |
201 | | | 201 | |
202 | sti_describe_screen(sc, scr); | | 202 | sti_describe_screen(sc, scr); |
203 | | | 203 | |
204 | return scr; | | 204 | return scr; |
205 | } | | 205 | } |
206 | | | 206 | |
207 | int | | 207 | int |
208 | sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt, | | 208 | sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt, |
209 | bus_space_handle_t romh, bus_addr_t *bases, u_int codebase) | | 209 | bus_space_handle_t romh, bus_addr_t *bases, u_int codebase) |
210 | { | | 210 | { |
211 | struct sti_dd *dd; | | 211 | struct sti_dd *dd; |
212 | int error, size, i; | | 212 | int error, size, i; |
213 | | | 213 | |
214 | KASSERT(rom != NULL); | | 214 | KASSERT(rom != NULL); |
215 | STI_ENABLE_ROM(rom->rom_softc); | | 215 | STI_ENABLE_ROM(rom->rom_softc); |
216 | | | 216 | |
217 | rom->iot = iot; | | 217 | rom->iot = iot; |
218 | rom->memt = memt; | | 218 | rom->memt = memt; |
219 | rom->romh = romh; | | 219 | rom->romh = romh; |
220 | rom->bases = bases; | | 220 | rom->bases = bases; |
221 | | | 221 | |
222 | /* | | 222 | /* |
223 | * Get ROM header and code function pointers. | | 223 | * Get ROM header and code function pointers. |
224 | */ | | 224 | */ |
225 | | | 225 | |
226 | dd = &rom->rom_dd; | | 226 | dd = &rom->rom_dd; |
227 | rom->rom_devtype = bus_space_read_1(memt, romh, 3); | | 227 | rom->rom_devtype = bus_space_read_1(memt, romh, 3); |
228 | if (rom->rom_devtype == STI_DEVTYPE1) { | | 228 | if (rom->rom_devtype == STI_DEVTYPE1) { |
229 | dd->dd_type = bus_space_read_1(memt, romh, 0x03); | | 229 | dd->dd_type = bus_space_read_1(memt, romh, 0x03); |
230 | dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); | | 230 | dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); |
231 | dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); | | 231 | dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); |
232 | dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); | | 232 | dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); |
233 | dd->dd_grid[0] = parseword(0x10); | | 233 | dd->dd_grid[0] = parseword(0x10); |
234 | dd->dd_grid[1] = parseword(0x20); | | 234 | dd->dd_grid[1] = parseword(0x20); |
235 | dd->dd_fntaddr = parseword(0x30) & ~3; | | 235 | dd->dd_fntaddr = parseword(0x30) & ~3; |
236 | dd->dd_maxst = parseword(0x40); | | 236 | dd->dd_maxst = parseword(0x40); |
237 | dd->dd_romend = parseword(0x50) & ~3; | | 237 | dd->dd_romend = parseword(0x50) & ~3; |
238 | dd->dd_reglst = parseword(0x60) & ~3; | | 238 | dd->dd_reglst = parseword(0x60) & ~3; |
239 | dd->dd_maxreent = parseshort(0x70); | | 239 | dd->dd_maxreent = parseshort(0x70); |
240 | dd->dd_maxtimo = parseshort(0x78); | | 240 | dd->dd_maxtimo = parseshort(0x78); |
241 | dd->dd_montbl = parseword(0x80) & ~3; | | 241 | dd->dd_montbl = parseword(0x80) & ~3; |
242 | dd->dd_udaddr = parseword(0x90) & ~3; | | 242 | dd->dd_udaddr = parseword(0x90) & ~3; |
243 | dd->dd_stimemreq = parseword(0xa0); | | 243 | dd->dd_stimemreq = parseword(0xa0); |
244 | dd->dd_udsize = parseword(0xb0); | | 244 | dd->dd_udsize = parseword(0xb0); |
245 | dd->dd_pwruse = parseshort(0xc0); | | 245 | dd->dd_pwruse = parseshort(0xc0); |
246 | dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); | | 246 | dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); |
247 | dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); | | 247 | dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); |
248 | dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); | | 248 | dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); |
249 | dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); | | 249 | dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); |
250 | dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); | | 250 | dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); |
251 | dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); | | 251 | dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); |
252 | dd->dd_cfbaddr = parseword(0xe0) & ~3; | | 252 | dd->dd_cfbaddr = parseword(0xe0) & ~3; |
253 | | | 253 | |
254 | codebase <<= 2; | | 254 | codebase <<= 2; |
255 | dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; | | 255 | dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; |
256 | dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3; | | 256 | dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3; |
257 | dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3; | | 257 | dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3; |
258 | dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3; | | 258 | dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3; |
259 | dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3; | | 259 | dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3; |
260 | dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3; | | 260 | dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3; |
261 | dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3; | | 261 | dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3; |
262 | dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3; | | 262 | dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3; |
263 | dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3; | | 263 | dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3; |
264 | dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3; | | 264 | dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3; |
265 | dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3; | | 265 | dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3; |
266 | dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3; | | 266 | dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3; |
267 | dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3; | | 267 | dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3; |
268 | dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3; | | 268 | dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3; |
269 | dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3; | | 269 | dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3; |
270 | dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3; | | 270 | dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3; |
271 | } else { /* STI_DEVTYPE4 */ | | 271 | } else { /* STI_DEVTYPE4 */ |
272 | bus_space_read_region_stream_4(memt, romh, 0, (uint32_t *)dd, | | 272 | bus_space_read_region_stream_4(memt, romh, 0, (uint32_t *)dd, |
273 | sizeof(*dd) / 4); | | 273 | sizeof(*dd) / 4); |
274 | /* fix pacode... */ | | 274 | /* fix pacode... */ |
275 | bus_space_read_region_stream_4(memt, romh, codebase, | | 275 | bus_space_read_region_stream_4(memt, romh, codebase, |
276 | (uint32_t *)dd->dd_pacode, sizeof(dd->dd_pacode) / 4); | | 276 | (uint32_t *)dd->dd_pacode, sizeof(dd->dd_pacode) / 4); |
277 | } | | 277 | } |
278 | | | 278 | |
279 | STI_DISABLE_ROM(rom->rom_softc); | | 279 | STI_DISABLE_ROM(rom->rom_softc); |
280 | | | 280 | |
281 | DPRINTF(("dd:\n" | | 281 | DPRINTF(("dd:\n" |
282 | "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n" | | 282 | "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n" |
283 | "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" | | 283 | "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" |
284 | "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" | | 284 | "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" |
285 | "code=", | | 285 | "code=", |
286 | dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, | | 286 | dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, |
287 | dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst, | | 287 | dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst, |
288 | dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, | | 288 | dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, |
289 | dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, | | 289 | dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, |
290 | dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr)); | | 290 | dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr)); |
291 | DPRINTF(("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", | | 291 | DPRINTF(("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", |
292 | dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], | | 292 | dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], |
293 | dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], | | 293 | dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], |
294 | dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], | | 294 | dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], |
295 | dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], | | 295 | dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], |
296 | dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], | | 296 | dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], |
297 | dd->dd_pacode[0xf])); | | 297 | dd->dd_pacode[0xf])); |
298 | | | 298 | |
299 | /* | | 299 | /* |
300 | * Figure out how many bytes we need for the STI code. | | 300 | * Figure out how many bytes we need for the STI code. |
301 | * Note there could be fewer than STI_END pointer entries | | 301 | * Note there could be fewer than STI_END pointer entries |
302 | * populated, especially on older devices. | | 302 | * populated, especially on older devices. |
303 | */ | | 303 | */ |
304 | for (i = STI_END; dd->dd_pacode[i] == 0; i--) | | 304 | for (i = STI_END; dd->dd_pacode[i] == 0; i--) |
305 | ; | | 305 | ; |
306 | | | 306 | |
307 | size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; | | 307 | size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; |
308 | | | 308 | |
309 | if (rom->rom_devtype == STI_DEVTYPE1) | | 309 | if (rom->rom_devtype == STI_DEVTYPE1) |
310 | size = (size + 3) / 4; | | 310 | size = (size + 3) / 4; |
311 | if (size == 0) { | | 311 | if (size == 0) { |
312 | aprint_error(": no code for the requested platform\n"); | | 312 | aprint_error(": no code for the requested platform\n"); |
313 | return EINVAL; | | 313 | return EINVAL; |
314 | } | | 314 | } |
315 | | | 315 | |
316 | if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size), 0, | | 316 | if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size), 0, |
317 | UVM_KMF_WIRED))) { | | 317 | UVM_KMF_WIRED))) { |
318 | aprint_error(": cannot allocate %u bytes for code\n", size); | | 318 | aprint_error(": cannot allocate %u bytes for code\n", size); |
319 | return ENOMEM; | | 319 | return ENOMEM; |
320 | } | | 320 | } |
321 | DPRINTF(("code=0x%lx[%x]\n", rom->rom_code, size)); | | 321 | DPRINTF(("code=0x%lx[%x]\n", rom->rom_code, size)); |
322 | | | 322 | |
323 | /* | | 323 | /* |
324 | * Copy code into memory and make it executable. | | 324 | * Copy code into memory and make it executable. |
325 | */ | | 325 | */ |
326 | | | 326 | |
327 | STI_ENABLE_ROM(rom->rom_softc); | | 327 | STI_ENABLE_ROM(rom->rom_softc); |
328 | | | 328 | |
329 | if (rom->rom_devtype == STI_DEVTYPE1) { | | 329 | if (rom->rom_devtype == STI_DEVTYPE1) { |
330 | uint8_t *p; | | 330 | uint8_t *p; |
331 | uint32_t addr, eaddr; | | 331 | uint32_t addr, eaddr; |
332 | | | 332 | |
333 | p = (uint8_t *)rom->rom_code; | | 333 | p = (uint8_t *)rom->rom_code; |
334 | | | 334 | |
335 | for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; | | 335 | for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; |
336 | addr < eaddr; addr += 4 ) { | | 336 | addr < eaddr; addr += 4 ) { |
337 | *p++ = bus_space_read_4(memt, romh, addr) & 0xff; | | 337 | *p++ = bus_space_read_4(memt, romh, addr) & 0xff; |
338 | } | | 338 | } |
339 | } else { /* STI_DEVTYPE4 */ | | 339 | } else { /* STI_DEVTYPE4 */ |
340 | bus_space_read_region_stream_4(memt, romh, | | 340 | bus_space_read_region_stream_4(memt, romh, |
341 | dd->dd_pacode[STI_BEGIN], (uint32_t *)rom->rom_code, | | 341 | dd->dd_pacode[STI_BEGIN], (uint32_t *)rom->rom_code, |
342 | size / 4); | | 342 | size / 4); |
343 | } | | 343 | } |
344 | | | 344 | |
345 | STI_DISABLE_ROM(rom->rom_softc); | | 345 | STI_DISABLE_ROM(rom->rom_softc); |
346 | | | 346 | |
347 | if ((error = uvm_map_protect(kernel_map, rom->rom_code, | | 347 | if ((error = uvm_map_protect(kernel_map, rom->rom_code, |
348 | rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) { | | 348 | rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) { |
349 | aprint_error(": uvm_map_protect failed (%d)\n", error); | | 349 | aprint_error(": uvm_map_protect failed (%d)\n", error); |
350 | uvm_km_free(kernel_map, rom->rom_code, round_page(size), | | 350 | uvm_km_free(kernel_map, rom->rom_code, round_page(size), |
351 | UVM_KMF_WIRED); | | 351 | UVM_KMF_WIRED); |
352 | return error; | | 352 | return error; |
353 | } | | 353 | } |
354 | | | 354 | |
355 | /* | | 355 | /* |
356 | * Setup code function pointers. | | 356 | * Setup code function pointers. |
357 | */ | | 357 | */ |
358 | | | 358 | |
359 | #define O(i) \ | | 359 | #define O(i) \ |
360 | (dd->dd_pacode[(i)] == 0 ? 0 : \ | | 360 | (dd->dd_pacode[(i)] == 0 ? 0 : \ |
361 | (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ | | 361 | (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ |
362 | (rom->rom_devtype == STI_DEVTYPE1 ? 4 : 1))) | | 362 | (rom->rom_devtype == STI_DEVTYPE1 ? 4 : 1))) |
363 | | | 363 | |
364 | rom->init = (sti_init_t)O(STI_INIT_GRAPH); | | 364 | rom->init = (sti_init_t)O(STI_INIT_GRAPH); |
365 | rom->mgmt = (sti_mgmt_t)O(STI_STATE_MGMT); | | 365 | rom->mgmt = (sti_mgmt_t)O(STI_STATE_MGMT); |
366 | rom->unpmv = (sti_unpmv_t)O(STI_FONT_UNPMV); | | 366 | rom->unpmv = (sti_unpmv_t)O(STI_FONT_UNPMV); |
367 | rom->blkmv = (sti_blkmv_t)O(STI_BLOCK_MOVE); | | 367 | rom->blkmv = (sti_blkmv_t)O(STI_BLOCK_MOVE); |
368 | rom->test = (sti_test_t)O(STI_SELF_TEST); | | 368 | rom->test = (sti_test_t)O(STI_SELF_TEST); |
369 | rom->exhdl = (sti_exhdl_t)O(STI_EXCEP_HDLR); | | 369 | rom->exhdl = (sti_exhdl_t)O(STI_EXCEP_HDLR); |
370 | rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); | | 370 | rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); |
371 | rom->scment = (sti_scment_t)O(STI_SCM_ENT); | | 371 | rom->scment = (sti_scment_t)O(STI_SCM_ENT); |
372 | rom->dmac = (sti_dmac_t)O(STI_DMA_CTRL); | | 372 | rom->dmac = (sti_dmac_t)O(STI_DMA_CTRL); |
373 | rom->flowc = (sti_flowc_t)O(STI_FLOW_CTRL); | | 373 | rom->flowc = (sti_flowc_t)O(STI_FLOW_CTRL); |
374 | rom->utiming = (sti_utiming_t)O(STI_UTIMING); | | 374 | rom->utiming = (sti_utiming_t)O(STI_UTIMING); |
375 | rom->pmgr = (sti_pmgr_t)O(STI_PROC_MGR); | | 375 | rom->pmgr = (sti_pmgr_t)O(STI_PROC_MGR); |
376 | rom->util = (sti_util_t)O(STI_UTIL); | | 376 | rom->util = (sti_util_t)O(STI_UTIL); |
377 | | | 377 | |
378 | #undef O | | 378 | #undef O |
379 | | | 379 | |
380 | /* | | 380 | /* |
381 | * Set colormap entry is not implemented until 8.04, so force | | 381 | * Set colormap entry is not implemented until 8.04, so force |
382 | * a NULL pointer here. | | 382 | * a NULL pointer here. |
383 | */ | | 383 | */ |
384 | if (dd->dd_grrev < STI_REVISION(8, 4)) { | | 384 | if (dd->dd_grrev < STI_REVISION(8, 4)) { |
385 | rom->scment = NULL; | | 385 | rom->scment = NULL; |
386 | } | | 386 | } |
387 | | | 387 | |
388 | return 0; | | 388 | return 0; |
389 | } | | 389 | } |
390 | | | 390 | |
391 | /* | | 391 | /* |
392 | * Map all regions. | | 392 | * Map all regions. |
393 | */ | | 393 | */ |
394 | void | | 394 | void |
395 | sti_region_setup(struct sti_screen *scr) | | 395 | sti_region_setup(struct sti_screen *scr) |
396 | { | | 396 | { |
397 | struct sti_rom *rom = scr->scr_rom; | | 397 | struct sti_rom *rom = scr->scr_rom; |
398 | bus_space_tag_t memt = rom->memt; | | 398 | bus_space_tag_t memt = rom->memt; |
399 | bus_space_handle_t romh = rom->romh; | | 399 | bus_space_handle_t romh = rom->romh; |
400 | bus_addr_t *bases = rom->bases; | | 400 | bus_addr_t *bases = rom->bases; |
401 | struct sti_dd *dd = &rom->rom_dd; | | 401 | struct sti_dd *dd = &rom->rom_dd; |
402 | struct sti_cfg *cc = &scr->scr_cfg; | | 402 | struct sti_cfg *cc = &scr->scr_cfg; |
403 | struct sti_region regions[STI_REGION_MAX], *r; | | 403 | struct sti_region regions[STI_REGION_MAX], *r; |
404 | u_int regno, regcnt; | | 404 | u_int regno, regcnt; |
405 | bus_addr_t addr; | | 405 | bus_addr_t addr; |
406 | | | 406 | |
407 | DPRINTF(("stiregions @ %x:\n", dd->dd_reglst)); | | 407 | DPRINTF(("stiregions @ %x:\n", dd->dd_reglst)); |
408 | | | 408 | |
409 | /* | | 409 | /* |
410 | * Read the region information. | | 410 | * Read the region information. |
411 | */ | | 411 | */ |
412 | | | 412 | |
413 | STI_ENABLE_ROM(rom->rom_softc); | | 413 | STI_ENABLE_ROM(rom->rom_softc); |
414 | | | 414 | |
415 | if (rom->rom_devtype == STI_DEVTYPE1) { | | 415 | if (rom->rom_devtype == STI_DEVTYPE1) { |
416 | for (regno = 0; regno < STI_REGION_MAX; regno++) | | 416 | for (regno = 0; regno < STI_REGION_MAX; regno++) |
417 | *(u_int *)(regions + regno) = | | 417 | *(u_int *)(regions + regno) = |
418 | parseword(dd->dd_reglst + regno * 0x10); | | 418 | parseword(dd->dd_reglst + regno * 0x10); |
419 | } else { | | 419 | } else { |
420 | bus_space_read_region_stream_4(memt, romh, dd->dd_reglst, | | 420 | bus_space_read_region_stream_4(memt, romh, dd->dd_reglst, |
421 | (uint32_t *)regions, sizeof(regions) / 4); | | 421 | (uint32_t *)regions, sizeof(regions) / 4); |
422 | } | | 422 | } |
423 | | | 423 | |
424 | STI_DISABLE_ROM(rom->rom_softc); | | 424 | STI_DISABLE_ROM(rom->rom_softc); |
425 | | | 425 | |
426 | /* | | 426 | /* |
427 | * Count them. | | 427 | * Count them. |
428 | */ | | 428 | */ |
429 | | | 429 | |
430 | for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++) | | 430 | for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++) |
431 | if (r->last) | | 431 | if (r->last) |
432 | break; | | 432 | break; |
433 | regcnt++; | | 433 | regcnt++; |
434 | | | 434 | |
435 | /* | | 435 | /* |
436 | * Map them. | | 436 | * Map them. |
437 | */ | | 437 | */ |
438 | | | 438 | |
439 | for (regno = 0, r = regions; regno < regcnt; regno++, r++) { | | 439 | for (regno = 0, r = regions; regno < regcnt; regno++, r++) { |
440 | if (r->length == 0) | | 440 | if (r->length == 0) |
441 | continue; | | 441 | continue; |
442 | | | 442 | |
443 | /* | | 443 | /* |
444 | * Assume an existing mapping exists. | | 444 | * Assume an existing mapping exists. |
445 | */ | | 445 | */ |
446 | addr = bases[regno] + (r->offset << PGSHIFT); | | 446 | addr = bases[regno] + (r->offset << PGSHIFT); |
447 | DPRINTF(("%08x @ 0x%08x%s%s%s%s", | | 447 | DPRINTF(("%08x @ 0x%08x%s%s%s%s", |
448 | r->length << PGSHIFT, (int)addr, r->sys_only ? " sys" : "", | | 448 | r->length << PGSHIFT, (int)addr, r->sys_only ? " sys" : "", |
449 | r->cache ? " cache" : "", r->btlb ? " btlb" : "", | | 449 | r->cache ? " cache" : "", r->btlb ? " btlb" : "", |
450 | r->last ? " last" : "")); | | 450 | r->last ? " last" : "")); |
451 | | | 451 | |
452 | /* | | 452 | /* |
453 | * Region #0 is always the rom, and it should have been | | 453 | * Region #0 is always the rom, and it should have been |
454 | * mapped already. | | 454 | * mapped already. |
455 | * XXX This expects a 1:1 mapping... | | 455 | * XXX This expects a 1:1 mapping... |
456 | */ | | 456 | */ |
457 | if (regno == 0 && romh == bases[0]) { | | 457 | if (regno == 0 && romh == bases[0]) { |
458 | cc->regions[0] = addr; | | 458 | cc->regions[0] = addr; |
459 | DPRINTF(("\n")); | | 459 | DPRINTF(("\n")); |
460 | continue; | | 460 | continue; |
461 | } | | 461 | } |
462 | | | 462 | |
463 | if (bus_space_map(memt, addr, r->length << PGSHIFT, | | 463 | if (bus_space_map(memt, addr, r->length << PGSHIFT, |
464 | BUS_SPACE_MAP_LINEAR | (r->cache ? | | 464 | BUS_SPACE_MAP_LINEAR | (r->cache ? |
465 | BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) { | | 465 | BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) { |
466 | rom->regh[regno] = romh; /* XXX */ | | 466 | rom->regh[regno] = romh; /* XXX */ |
467 | DPRINTF((" - already mapped region\n")); | | 467 | DPRINTF((" - already mapped region\n")); |
468 | } else { | | 468 | } else { |
469 | addr = (bus_addr_t) | | 469 | addr = (bus_addr_t) |
470 | bus_space_vaddr(memt, rom->regh[regno]); | | 470 | bus_space_vaddr(memt, rom->regh[regno]); |
471 | if (regno == 1) { | | 471 | if (regno == 1) { |
472 | DPRINTF((" - fb")); | | 472 | DPRINTF((" - fb")); |
473 | scr->fbaddr = addr; | | 473 | scr->fbaddr = addr; |
474 | scr->fblen = r->length << PGSHIFT; | | 474 | scr->fblen = r->length << PGSHIFT; |
475 | } | | 475 | } |
476 | DPRINTF(("\n")); | | 476 | DPRINTF(("\n")); |
477 | } | | 477 | } |
478 | | | 478 | |
479 | cc->regions[regno] = addr; | | 479 | cc->regions[regno] = addr; |
480 | } | | 480 | } |
481 | | | 481 | |
482 | #ifdef STIDEBUG | | 482 | #ifdef STIDEBUG |
483 | /* | | 483 | /* |
484 | * Make sure we'll trap accessing unmapped regions | | 484 | * Make sure we'll trap accessing unmapped regions |
485 | */ | | 485 | */ |
486 | for (regno = 0; regno < STI_REGION_MAX; regno++) | | 486 | for (regno = 0; regno < STI_REGION_MAX; regno++) |
487 | if (cc->regions[regno] == 0) | | 487 | if (cc->regions[regno] == 0) |
488 | cc->regions[regno] = 0x81234567; | | 488 | cc->regions[regno] = 0x81234567; |
489 | #endif | | 489 | #endif |
490 | } | | 490 | } |
491 | | | 491 | |
492 | int | | 492 | int |
493 | sti_screen_setup(struct sti_screen *scr, int flags) | | 493 | sti_screen_setup(struct sti_screen *scr, int flags) |
494 | { | | 494 | { |
495 | struct sti_rom *rom = scr->scr_rom; | | 495 | struct sti_rom *rom = scr->scr_rom; |
496 | bus_space_tag_t memt = rom->memt; | | 496 | bus_space_tag_t memt = rom->memt; |
497 | bus_space_handle_t romh = rom->romh; | | 497 | bus_space_handle_t romh = rom->romh; |
498 | struct sti_dd *dd = &rom->rom_dd; | | 498 | struct sti_dd *dd = &rom->rom_dd; |
499 | struct sti_cfg *cc = &scr->scr_cfg; | | 499 | struct sti_cfg *cc = &scr->scr_cfg; |
500 | struct sti_inqconfout cfg; | | 500 | struct sti_inqconfout cfg; |
501 | struct sti_einqconfout ecfg; | | 501 | struct sti_einqconfout ecfg; |
502 | #ifdef STIDEBUG | | 502 | #ifdef STIDEBUG |
503 | char buf[256]; | | 503 | char buf[256]; |
504 | #endif | | 504 | #endif |
505 | int error, i; | | 505 | int error, i; |
506 | int geometry_kluge = 0; | | 506 | int geometry_kluge = 0; |
507 | u_int fontindex = 0; | | 507 | u_int fontindex = 0; |
508 | | | 508 | |
509 | KASSERT(scr != NULL); | | 509 | KASSERT(scr != NULL); |
510 | memset(cc, 0, sizeof(*cc)); | | 510 | memset(cc, 0, sizeof(*cc)); |
511 | cc->ext_cfg = &scr->scr_ecfg; | | 511 | cc->ext_cfg = &scr->scr_ecfg; |
512 | memset(cc->ext_cfg, 0, sizeof(*cc->ext_cfg)); | | 512 | memset(cc->ext_cfg, 0, sizeof(*cc->ext_cfg)); |
513 | | | 513 | |
514 | if (dd->dd_stimemreq) { | | 514 | if (dd->dd_stimemreq) { |
515 | scr->scr_ecfg.addr = | | 515 | scr->scr_ecfg.addr = |
516 | malloc(dd->dd_stimemreq, M_DEVBUF, M_WAITOK); | | 516 | malloc(dd->dd_stimemreq, M_DEVBUF, M_WAITOK); |
517 | } | | 517 | } |
518 | | | 518 | |
519 | sti_region_setup(scr); | | 519 | sti_region_setup(scr); |
520 | | | 520 | |
521 | if ((error = sti_init(scr, 0))) { | | 521 | if ((error = sti_init(scr, 0))) { |
522 | aprint_error(": cannot initialize (%d)\n", error); | | 522 | aprint_error(": cannot initialize (%d)\n", error); |
523 | goto fail; | | 523 | goto fail; |
524 | } | | 524 | } |
525 | | | 525 | |
526 | memset(&cfg, 0, sizeof(cfg)); | | 526 | memset(&cfg, 0, sizeof(cfg)); |
527 | memset(&ecfg, 0, sizeof(ecfg)); | | 527 | memset(&ecfg, 0, sizeof(ecfg)); |
528 | cfg.ext = &ecfg; | | 528 | cfg.ext = &ecfg; |
529 | if ((error = sti_inqcfg(scr, &cfg))) { | | 529 | if ((error = sti_inqcfg(scr, &cfg))) { |
530 | aprint_error(": error %d inquiring config\n", error); | | 530 | aprint_error(": error %d inquiring config\n", error); |
531 | goto fail; | | 531 | goto fail; |
532 | } | | 532 | } |
533 | | | 533 | |
534 | /* | | 534 | /* |
535 | * Older (rev 8.02) boards report wrong offset values, | | 535 | * Older (rev 8.02) boards report wrong offset values, |
536 | * similar to the displayable area size, at least in m68k mode. | | 536 | * similar to the displayable area size, at least in m68k mode. |
537 | * Attempt to detect this and adjust here. | | 537 | * Attempt to detect this and adjust here. |
538 | */ | | 538 | */ |
539 | if (cfg.owidth == cfg.width && | | 539 | if (cfg.owidth == cfg.width && |
540 | cfg.oheight == cfg.height) | | 540 | cfg.oheight == cfg.height) |
541 | geometry_kluge = 1; | | 541 | geometry_kluge = 1; |
542 | | | 542 | |
543 | if (geometry_kluge) { | | 543 | if (geometry_kluge) { |
544 | scr->scr_cfg.oscr_width = cfg.owidth = | | 544 | scr->scr_cfg.oscr_width = cfg.owidth = |
545 | cfg.fbwidth - cfg.width; | | 545 | cfg.fbwidth - cfg.width; |
546 | scr->scr_cfg.oscr_height = cfg.oheight = | | 546 | scr->scr_cfg.oscr_height = cfg.oheight = |
547 | cfg.fbheight - cfg.height; | | 547 | cfg.fbheight - cfg.height; |
548 | } | | 548 | } |
549 | | | 549 | |
550 | /* | | 550 | /* |
551 | * Save a few fields for sti_describe_screen() later | | 551 | * Save a few fields for sti_describe_screen() later |
552 | */ | | 552 | */ |
553 | scr->fbheight = cfg.fbheight; | | 553 | scr->fbheight = cfg.fbheight; |
554 | scr->fbwidth = cfg.fbwidth; | | 554 | scr->fbwidth = cfg.fbwidth; |
555 | scr->oheight = cfg.oheight; | | 555 | scr->oheight = cfg.oheight; |
556 | scr->owidth = cfg.owidth; | | 556 | scr->owidth = cfg.owidth; |
557 | memcpy(scr->name, cfg.name, sizeof(scr->name)); | | 557 | memcpy(scr->name, cfg.name, sizeof(scr->name)); |
558 | | | 558 | |
559 | if ((error = sti_init(scr, STI_TEXTMODE | flags))) { | | 559 | if ((error = sti_init(scr, STI_TEXTMODE | flags))) { |
560 | aprint_error(": cannot initialize (%d)\n", error); | | 560 | aprint_error(": cannot initialize (%d)\n", error); |
561 | goto fail; | | 561 | goto fail; |
562 | } | | 562 | } |
563 | #ifdef STIDEBUG | | 563 | #ifdef STIDEBUG |
564 | snprintb(buf, sizeof(buf), STI_INQCONF_BITS, cfg.attributes); | | 564 | snprintb(buf, sizeof(buf), STI_INQCONF_BITS, cfg.attributes); |
565 | DPRINTF(("conf: bpp=%d planes=%d attr=%s\n" | | 565 | DPRINTF(("conf: bpp=%d planes=%d attr=%s\n" |
566 | "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, | | 566 | "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, |
567 | cfg.planes, buf, | | 567 | cfg.planes, buf, |
568 | ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2], | | 568 | ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2], |
569 | ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2])); | | 569 | ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2])); |
570 | #endif | | 570 | #endif |
571 | scr->scr_bpp = cfg.bppu; | | 571 | scr->scr_bpp = cfg.bppu; |
572 | | | 572 | |
573 | /* | | 573 | /* |
574 | * Although scr->scr_ecfg.current_monitor is not filled by | | 574 | * Although scr->scr_ecfg.current_monitor is not filled by |
575 | * sti_init() as expected, we can nevertheless walk the monitor | | 575 | * sti_init() as expected, we can nevertheless walk the monitor |
576 | * list, if there is any, and if we find a mode matching our | | 576 | * list, if there is any, and if we find a mode matching our |
577 | * resolution, pick its font index. | | 577 | * resolution, pick its font index. |
578 | */ | | 578 | */ |
579 | if (dd->dd_montbl != 0) { | | 579 | if (dd->dd_montbl != 0) { |
580 | STI_ENABLE_ROM(rom->rom_softc); | | 580 | STI_ENABLE_ROM(rom->rom_softc); |
581 | | | 581 | |
582 | for (i = 0; i < dd->dd_nmon; i++) { | | 582 | for (i = 0; i < dd->dd_nmon; i++) { |
583 | u_int offs = dd->dd_montbl + 8 * i; | | 583 | u_int offs = dd->dd_montbl + 8 * i; |
584 | uint32_t m[2]; | | 584 | uint32_t m[2]; |
585 | sti_mon_t mon = (void *)m; | | 585 | sti_mon_t mon = (void *)m; |
586 | if (rom->rom_devtype == STI_DEVTYPE1) { | | 586 | if (rom->rom_devtype == STI_DEVTYPE1) { |
587 | m[0] = parseword(4 * offs); | | 587 | m[0] = parseword(4 * offs); |
588 | m[1] = parseword(4 * (offs + 4)); | | 588 | m[1] = parseword(4 * (offs + 4)); |
589 | } else { | | 589 | } else { |
590 | bus_space_read_region_stream_4(memt, romh, offs, | | 590 | bus_space_read_region_stream_4(memt, romh, offs, |
591 | (uint32_t *)mon, sizeof(*mon) / 4); | | 591 | (uint32_t *)mon, sizeof(*mon) / 4); |
592 | } | | 592 | } |
593 | | | 593 | |
594 | if (mon->width == scr->scr_cfg.scr_width && | | 594 | if (mon->width == scr->scr_cfg.scr_width && |
595 | mon->height == scr->scr_cfg.scr_height) { | | 595 | mon->height == scr->scr_cfg.scr_height) { |
596 | fontindex = mon->font; | | 596 | fontindex = mon->font; |
597 | break; | | 597 | break; |
598 | } | | 598 | } |
599 | } | | 599 | } |
600 | | | 600 | |
601 | STI_DISABLE_ROM(rom->rom_softc); | | 601 | STI_DISABLE_ROM(rom->rom_softc); |
602 | | | 602 | |
603 | DPRINTF(("font index: %d\n", fontindex)); | | 603 | DPRINTF(("font index: %d\n", fontindex)); |
604 | } | | 604 | } |
605 | | | 605 | |
606 | if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { | | 606 | if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { |
607 | aprint_error(": cannot fetch fonts (%d)\n", error); | | 607 | aprint_error(": cannot fetch fonts (%d)\n", error); |
608 | goto fail; | | 608 | goto fail; |
609 | } | | 609 | } |
610 | | | 610 | |
611 | /* | | 611 | /* |
612 | * setup screen descriptions: | | 612 | * setup screen descriptions: |
613 | * figure number of fonts supported; | | 613 | * figure number of fonts supported; |
614 | * allocate wscons structures; | | 614 | * allocate wscons structures; |
615 | * calculate dimensions. | | 615 | * calculate dimensions. |
616 | */ | | 616 | */ |
617 | | | 617 | |
618 | scr->scr_wsd.name = "std"; | | 618 | scr->scr_wsd.name = "std"; |
619 | scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width; | | 619 | scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width; |
620 | scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height; | | 620 | scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height; |
621 | scr->scr_wsd.textops = &sti_emulops; | | 621 | scr->scr_wsd.textops = &sti_emulops; |
622 | scr->scr_wsd.fontwidth = scr->scr_curfont.width; | | 622 | scr->scr_wsd.fontwidth = scr->scr_curfont.width; |
623 | scr->scr_wsd.fontheight = scr->scr_curfont.height; | | 623 | scr->scr_wsd.fontheight = scr->scr_curfont.height; |
624 | scr->scr_wsd.capabilities = WSSCREEN_REVERSE; | | 624 | scr->scr_wsd.capabilities = WSSCREEN_REVERSE; |
625 | | | 625 | |
626 | scr->scr_scrlist[0] = &scr->scr_wsd; | | 626 | scr->scr_scrlist[0] = &scr->scr_wsd; |
627 | scr->scr_screenlist.nscreens = 1; | | 627 | scr->scr_screenlist.nscreens = 1; |
628 | scr->scr_screenlist.screens = scr->scr_scrlist; | | 628 | scr->scr_screenlist.screens = scr->scr_scrlist; |
629 | | | 629 | |
630 | #ifndef SMALL_KERNEL | | 630 | #ifndef SMALL_KERNEL |
631 | /* | | 631 | /* |
632 | * Decide which board-specific routines to use. | | 632 | * Decide which board-specific routines to use. |
633 | */ | | 633 | */ |
634 | | | 634 | |
635 | switch (dd->dd_grid[0]) { | | 635 | switch (dd->dd_grid[0]) { |
636 | case STI_DD_CRX: | | 636 | case STI_DD_CRX: |
637 | scr->setupfb = ngle_elk_setupfb; | | 637 | scr->setupfb = ngle_elk_setupfb; |
638 | scr->putcmap = ngle_putcmap; | | 638 | scr->putcmap = ngle_putcmap; |
639 | | | 639 | |
640 | scr->reg10_value = 0x13601000; | | 640 | scr->reg10_value = 0x13601000; |
641 | if (scr->scr_bpp > 8) | | 641 | if (scr->scr_bpp > 8) |
642 | scr->reg12_value = NGLE_BUFF1_CMAP3; | | 642 | scr->reg12_value = NGLE_BUFF1_CMAP3; |
643 | else | | 643 | else |
644 | scr->reg12_value = NGLE_BUFF1_CMAP0; | | 644 | scr->reg12_value = NGLE_BUFF1_CMAP0; |
645 | scr->cmap_finish_register = NGLE_REG_1; | | 645 | scr->cmap_finish_register = NGLE_REG_1; |
646 | break; | | 646 | break; |
647 | | | 647 | |
648 | case STI_DD_TIMBER: | | 648 | case STI_DD_TIMBER: |
649 | scr->setupfb = ngle_timber_setupfb; | | 649 | scr->setupfb = ngle_timber_setupfb; |
650 | scr->putcmap = ngle_putcmap; | | 650 | scr->putcmap = ngle_putcmap; |
651 | | | 651 | |
652 | scr->reg10_value = 0x13602000; | | 652 | scr->reg10_value = 0x13602000; |
653 | scr->reg12_value = NGLE_BUFF1_CMAP0; | | 653 | scr->reg12_value = NGLE_BUFF1_CMAP0; |
654 | scr->cmap_finish_register = NGLE_REG_1; | | 654 | scr->cmap_finish_register = NGLE_REG_1; |
655 | break; | | 655 | break; |
656 | | | 656 | |
657 | case STI_DD_ARTIST: | | 657 | case STI_DD_ARTIST: |
658 | scr->setupfb = ngle_artist_setupfb; | | 658 | scr->setupfb = ngle_artist_setupfb; |
659 | scr->putcmap = ngle_putcmap; | | 659 | scr->putcmap = ngle_putcmap; |
660 | | | 660 | |
661 | scr->reg10_value = 0x13601000; | | 661 | scr->reg10_value = 0x13601000; |
662 | scr->reg12_value = NGLE_ARTIST_CMAP0; | | 662 | scr->reg12_value = NGLE_ARTIST_CMAP0; |
663 | scr->cmap_finish_register = NGLE_REG_26; | | 663 | scr->cmap_finish_register = NGLE_REG_26; |
664 | break; | | 664 | break; |
665 | | | 665 | |
666 | case STI_DD_EG: | | 666 | case STI_DD_EG: |
667 | scr->setupfb = ngle_artist_setupfb; | | 667 | scr->setupfb = ngle_artist_setupfb; |
668 | scr->putcmap = ngle_putcmap; | | 668 | scr->putcmap = ngle_putcmap; |
669 | | | 669 | |
670 | scr->reg10_value = 0x13601000; | | 670 | scr->reg10_value = 0x13601000; |
671 | if (scr->scr_bpp > 8) { | | 671 | if (scr->scr_bpp > 8) { |
672 | scr->reg12_value = NGLE_BUFF1_CMAP3; | | 672 | scr->reg12_value = NGLE_BUFF1_CMAP3; |
673 | scr->cmap_finish_register = NGLE_REG_1; | | 673 | scr->cmap_finish_register = NGLE_REG_1; |
674 | } else { | | 674 | } else { |
675 | scr->reg12_value = NGLE_ARTIST_CMAP0; | | 675 | scr->reg12_value = NGLE_ARTIST_CMAP0; |
676 | scr->cmap_finish_register = NGLE_REG_26; | | 676 | scr->cmap_finish_register = NGLE_REG_26; |
677 | } | | 677 | } |
678 | break; | | 678 | break; |
679 | | | 679 | |
680 | case STI_DD_GRX: | | 680 | case STI_DD_GRX: |
681 | case STI_DD_CRX24: | | 681 | case STI_DD_CRX24: |
682 | case STI_DD_EVRX: | | 682 | case STI_DD_EVRX: |
683 | case STI_DD_3X2V: | | 683 | case STI_DD_3X2V: |
684 | case STI_DD_DUAL_CRX: | | 684 | case STI_DD_DUAL_CRX: |
685 | case STI_DD_HCRX: | | 685 | case STI_DD_HCRX: |
686 | case STI_DD_LEGO: | | 686 | case STI_DD_LEGO: |
687 | case STI_DD_SUMMIT: | | 687 | case STI_DD_SUMMIT: |
688 | case STI_DD_PINNACLE: | | 688 | case STI_DD_PINNACLE: |
689 | default: | | 689 | default: |
690 | scr->setupfb = NULL; | | 690 | scr->setupfb = NULL; |
691 | scr->putcmap = | | 691 | scr->putcmap = |
692 | rom->scment == NULL ? NULL : ngle_default_putcmap; | | 692 | rom->scment == NULL ? NULL : ngle_default_putcmap; |
693 | break; | | 693 | break; |
694 | } | | 694 | } |
695 | #endif | | 695 | #endif |
696 | | | 696 | |
697 | return 0; | | 697 | return 0; |
698 | | | 698 | |
699 | fail: | | 699 | fail: |
700 | /* XXX free resources */ | | 700 | /* XXX free resources */ |
701 | if (scr->scr_ecfg.addr != NULL) { | | 701 | if (scr->scr_ecfg.addr != NULL) { |
702 | free(scr->scr_ecfg.addr, M_DEVBUF); | | 702 | free(scr->scr_ecfg.addr, M_DEVBUF); |
703 | scr->scr_ecfg.addr = NULL; | | 703 | scr->scr_ecfg.addr = NULL; |
704 | } | | 704 | } |
705 | | | 705 | |
706 | return ENXIO; | | 706 | return ENXIO; |
707 | } | | 707 | } |
708 | | | 708 | |
709 | void | | 709 | void |
710 | sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr) | | 710 | sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr) |
711 | { | | 711 | { |
712 | struct sti_font *fp = &scr->scr_curfont; | | 712 | struct sti_font *fp = &scr->scr_curfont; |
713 | | | 713 | |
714 | aprint_normal("%s: %s, %dx%d frame buffer, %dx%dx%d display\n", | | 714 | aprint_normal("%s: %s, %dx%d frame buffer, %dx%dx%d display\n", |
715 | device_xname(sc->sc_dev), scr->name, scr->fbwidth, scr->fbheight, | | 715 | device_xname(sc->sc_dev), scr->name, scr->fbwidth, scr->fbheight, |
716 | scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp); | | 716 | scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp); |
717 | | | 717 | |
718 | aprint_normal("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", | | 718 | aprint_normal("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", |
719 | device_xname(sc->sc_dev), fp->width, fp->height, | | 719 | device_xname(sc->sc_dev), fp->width, fp->height, |
720 | fp->type, fp->bpc, fp->first, fp->last); | | 720 | fp->type, fp->bpc, fp->first, fp->last); |
721 | } | | 721 | } |
722 | | | 722 | |
723 | void | | 723 | void |
724 | sti_describe(struct sti_softc *sc) | | 724 | sti_describe(struct sti_softc *sc) |
725 | { | | 725 | { |
726 | struct sti_rom *rom = sc->sc_rom; | | 726 | struct sti_rom *rom = sc->sc_rom; |
727 | struct sti_dd *dd = &rom->rom_dd; | | 727 | struct sti_dd *dd = &rom->rom_dd; |
728 | | | 728 | |
729 | aprint_normal(": rev %d.%02d;%d, ID 0x%08X%08X\n", | | 729 | aprint_normal(": rev %d.%02d;%d, ID 0x%08X%08X\n", |
730 | dd->dd_grrev >> 4, dd->dd_grrev & 0xf, | | 730 | dd->dd_grrev >> 4, dd->dd_grrev & 0xf, |
731 | dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]); | | 731 | dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]); |
732 | | | 732 | |
733 | if (sc->sc_scr != NULL) | | 733 | if (sc->sc_scr != NULL) |
734 | sti_describe_screen(sc, sc->sc_scr); | | 734 | sti_describe_screen(sc, sc->sc_scr); |
735 | } | | 735 | } |
736 | | | 736 | |
737 | /* | | 737 | /* |
738 | * Final part of attachment. On hppa where we use the PDC console | | 738 | * Final part of attachment. On hppa where we use the PDC console |
739 | * during autoconf, this has to be postponed until autoconf has | | 739 | * during autoconf, this has to be postponed until autoconf has |
740 | * completed. | | 740 | * completed. |
741 | */ | | 741 | */ |
742 | void | | 742 | void |
743 | sti_end_attach(struct sti_softc *sc) | | 743 | sti_end_attach(struct sti_softc *sc) |
744 | { | | 744 | { |
745 | struct sti_screen *scr = sc->sc_scr; | | 745 | struct sti_screen *scr = sc->sc_scr; |
746 | | | 746 | |
747 | if (scr == NULL) | | 747 | if (scr == NULL) |
748 | return; | | 748 | return; |
749 | #if NWSDISPLAY > 0 | | 749 | #if NWSDISPLAY > 0 |
750 | else { | | 750 | else { |
751 | struct wsemuldisplaydev_attach_args waa; | | 751 | struct wsemuldisplaydev_attach_args waa; |
752 | scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL; | | 752 | scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL; |
753 | | | 753 | |
754 | waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0; | | 754 | waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0; |
755 | waa.scrdata = &scr->scr_screenlist; | | 755 | waa.scrdata = &scr->scr_screenlist; |
756 | waa.accessops = &sti_accessops; | | 756 | waa.accessops = &sti_accessops; |
757 | waa.accesscookie = scr; | | 757 | waa.accesscookie = scr; |
758 | | | 758 | |
759 | /* attach as console if required */ | | 759 | /* attach as console if required */ |
760 | if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) { | | 760 | if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) { |
761 | long defattr; | | 761 | long defattr; |
762 | | | 762 | |
763 | sti_alloc_attr(scr, 0, 0, 0, &defattr); | | 763 | sti_alloc_attr(scr, 0, 0, 0, &defattr); |
764 | wsdisplay_cnattach(&scr->scr_wsd, scr, | | 764 | wsdisplay_cnattach(&scr->scr_wsd, scr, |
765 | 0, scr->scr_wsd.nrows - 1, defattr); | | 765 | 0, scr->scr_wsd.nrows - 1, defattr); |
766 | sc->sc_flags |= STI_ATTACHED; | | 766 | sc->sc_flags |= STI_ATTACHED; |
767 | } | | 767 | } |
768 | | | 768 | |
769 | config_found(sc->sc_dev, &waa, wsemuldisplaydevprint); | | 769 | config_found(sc->sc_dev, &waa, wsemuldisplaydevprint); |
770 | } | | 770 | } |
771 | #endif | | 771 | #endif |
772 | } | | 772 | } |
773 | | | 773 | |
774 | u_int | | 774 | u_int |
775 | sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh) | | 775 | sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh) |
776 | { | | 776 | { |
777 | int devtype; | | 777 | int devtype; |
778 | u_int romend; | | 778 | u_int romend; |
779 | | | 779 | |
780 | devtype = bus_space_read_1(memt, romh, 3); | | 780 | devtype = bus_space_read_1(memt, romh, 3); |
781 | if (devtype == STI_DEVTYPE4) { | | 781 | if (devtype == STI_DEVTYPE4) { |
782 | bus_space_read_region_stream_4(memt, romh, STI_DEV4_DD_ROMEND, | | 782 | bus_space_read_region_stream_4(memt, romh, STI_DEV4_DD_ROMEND, |
783 | (uint32_t *)&romend, 1); | | 783 | (uint32_t *)&romend, 1); |
784 | } else { | | 784 | } else { |
785 | romend = parseword(STI_DEV1_DD_ROMEND); | | 785 | romend = parseword(STI_DEV1_DD_ROMEND); |
786 | } | | 786 | } |
787 | | | 787 | |
788 | DPRINTF(("%s: %08x (%08x)\n", __func__, romend, round_page(romend))); | | 788 | DPRINTF(("%s: %08x (%08x)\n", __func__, romend, round_page(romend))); |
789 | | | 789 | |
790 | return round_page(romend); | | 790 | return round_page(romend); |
791 | } | | 791 | } |
792 | | | 792 | |
793 | int | | 793 | int |
794 | sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, | | 794 | sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, |
795 | uint32_t baseaddr, u_int fontindex) | | 795 | uint32_t baseaddr, u_int fontindex) |
796 | { | | 796 | { |
797 | struct sti_rom *rom = scr->scr_rom; | | 797 | struct sti_rom *rom = scr->scr_rom; |
798 | bus_space_tag_t memt = rom->memt; | | 798 | bus_space_tag_t memt = rom->memt; |
799 | bus_space_handle_t romh = rom->romh; | | 799 | bus_space_handle_t romh = rom->romh; |
800 | struct sti_font *fp = &scr->scr_curfont; | | 800 | struct sti_font *fp = &scr->scr_curfont; |
801 | uint32_t addr; | | 801 | uint32_t addr; |
802 | int size; | | 802 | int size; |
803 | #ifdef notyet | | 803 | #ifdef notyet |
804 | int uc; | | 804 | int uc; |
805 | struct { | | 805 | struct { |
806 | struct sti_unpmvflags flags; | | 806 | struct sti_unpmvflags flags; |
807 | struct sti_unpmvin in; | | 807 | struct sti_unpmvin in; |
808 | struct sti_unpmvout out; | | 808 | struct sti_unpmvout out; |
809 | } a; | | 809 | } a; |
810 | #endif | | 810 | #endif |
811 | | | 811 | |
812 | /* | | 812 | /* |
813 | * Get the first PROM font in memory | | 813 | * Get the first PROM font in memory |
814 | */ | | 814 | */ |
815 | | | 815 | |
816 | STI_ENABLE_ROM(rom->rom_softc); | | 816 | STI_ENABLE_ROM(rom->rom_softc); |
817 | | | 817 | |
818 | rescan: | | 818 | rescan: |
819 | addr = baseaddr; | | 819 | addr = baseaddr; |
820 | do { | | 820 | do { |
821 | if (rom->rom_devtype == STI_DEVTYPE1) { | | 821 | if (rom->rom_devtype == STI_DEVTYPE1) { |
822 | fp->first = parseshort(addr + 0x00); | | 822 | fp->first = parseshort(addr + 0x00); |
823 | fp->last = parseshort(addr + 0x08); | | 823 | fp->last = parseshort(addr + 0x08); |
824 | fp->width = bus_space_read_1(memt, romh, addr + 0x13); | | 824 | fp->width = bus_space_read_1(memt, romh, addr + 0x13); |
825 | fp->height = bus_space_read_1(memt, romh, addr + 0x17); | | 825 | fp->height = bus_space_read_1(memt, romh, addr + 0x17); |
826 | fp->type = bus_space_read_1(memt, romh, addr + 0x1b); | | 826 | fp->type = bus_space_read_1(memt, romh, addr + 0x1b); |
827 | fp->bpc = bus_space_read_1(memt, romh, addr + 0x1f); | | 827 | fp->bpc = bus_space_read_1(memt, romh, addr + 0x1f); |
828 | fp->next = parseword(addr + 0x20); | | 828 | fp->next = parseword(addr + 0x20); |
829 | fp->uheight= bus_space_read_1(memt, romh, addr + 0x33); | | 829 | fp->uheight= bus_space_read_1(memt, romh, addr + 0x33); |
830 | fp->uoffset= bus_space_read_1(memt, romh, addr + 0x37); | | 830 | fp->uoffset= bus_space_read_1(memt, romh, addr + 0x37); |
831 | } else { /* STI_DEVTYPE4 */ | | 831 | } else { /* STI_DEVTYPE4 */ |
832 | bus_space_read_region_stream_4(memt, romh, addr, | | 832 | bus_space_read_region_stream_4(memt, romh, addr, |
833 | (uint32_t *)fp, sizeof(struct sti_font) / 4); | | 833 | (uint32_t *)fp, sizeof(struct sti_font) / 4); |
834 | } | | 834 | } |
835 | | | 835 | |
836 | #ifdef STIDEBUG | | 836 | #ifdef STIDEBUG |
837 | STI_DISABLE_ROM(rom->rom_softc); | | 837 | STI_DISABLE_ROM(rom->rom_softc); |
838 | DPRINTF(("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", | | 838 | DPRINTF(("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", |
839 | device_xname(scr->scr_rom->rom_softc->sc_dev), fp->width, | | 839 | device_xname(scr->scr_rom->rom_softc->sc_dev), fp->width, |
840 | fp->height, fp->type, fp->bpc, fp->first, fp->last)); | | 840 | fp->height, fp->type, fp->bpc, fp->first, fp->last)); |
841 | STI_ENABLE_ROM(rom->rom_softc); | | 841 | STI_ENABLE_ROM(rom->rom_softc); |
842 | #endif | | 842 | #endif |
843 | | | 843 | |
844 | if (fontindex == 0) { | | 844 | if (fontindex == 0) { |
845 | size = sizeof(struct sti_font) + | | 845 | size = sizeof(struct sti_font) + |
846 | (fp->last - fp->first + 1) * fp->bpc; | | 846 | (fp->last - fp->first + 1) * fp->bpc; |
847 | if (rom->rom_devtype == STI_DEVTYPE1) | | 847 | if (rom->rom_devtype == STI_DEVTYPE1) |
848 | size *= 4; | | 848 | size *= 4; |
849 | scr->scr_romfont = malloc(size, M_DEVBUF, M_WAITOK); | | 849 | scr->scr_romfont = malloc(size, M_DEVBUF, M_WAITOK); |
850 | | | 850 | |
851 | bus_space_read_region_stream_4(memt, romh, addr, | | 851 | bus_space_read_region_stream_4(memt, romh, addr, |
852 | (uint32_t *)scr->scr_romfont, size / 4); | | 852 | (uint32_t *)scr->scr_romfont, size / 4); |
853 | break; | | 853 | break; |
854 | } | | 854 | } |
855 | | | 855 | |
856 | addr = baseaddr + fp->next; | | 856 | addr = baseaddr + fp->next; |
857 | fontindex--; | | 857 | fontindex--; |
858 | } while (fp->next != 0); | | 858 | } while (fp->next != 0); |
859 | | | 859 | |
860 | /* | | 860 | /* |
861 | * If our font index was bogus, we did not find the expected font. | | 861 | * If our font index was bogus, we did not find the expected font. |
862 | * In this case, pick the first one and be done with it. | | 862 | * In this case, pick the first one and be done with it. |
863 | */ | | 863 | */ |
864 | if (fp->next == 0 && scr->scr_romfont == NULL) { | | 864 | if (fp->next == 0 && scr->scr_romfont == NULL) { |
865 | fontindex = 0; | | 865 | fontindex = 0; |
866 | goto rescan; | | 866 | goto rescan; |
867 | } | | 867 | } |
868 | | | 868 | |
869 | STI_DISABLE_ROM(rom->rom_softc); | | 869 | STI_DISABLE_ROM(rom->rom_softc); |
870 | | | 870 | |
871 | #ifdef notyet | | 871 | #ifdef notyet |
872 | /* | | 872 | /* |
873 | * If there is enough room in the off-screen framebuffer memory, | | 873 | * If there is enough room in the off-screen framebuffer memory, |
874 | * display all the characters there in order to display them | | 874 | * display all the characters there in order to display them |
875 | * faster with blkmv operations rather than unpmv later on. | | 875 | * faster with blkmv operations rather than unpmv later on. |
876 | */ | | 876 | */ |
877 | if (size <= cfg->fbheight * | | 877 | if (size <= cfg->fbheight * |
878 | (cfg->fbwidth - cfg->width - cfg->owidth)) { | | 878 | (cfg->fbwidth - cfg->width - cfg->owidth)) { |
879 | memset(&a, 0, sizeof(a)); | | 879 | memset(&a, 0, sizeof(a)); |
880 | a.flags.flags = STI_UNPMVF_WAIT; | | 880 | a.flags.flags = STI_UNPMVF_WAIT; |
881 | a.in.fg_colour = STI_COLOUR_WHITE; | | 881 | a.in.fg_colour = STI_COLOUR_WHITE; |
882 | a.in.bg_colour = STI_COLOUR_BLACK; | | 882 | a.in.bg_colour = STI_COLOUR_BLACK; |
883 | a.in.font_addr = scr->scr_romfont; | | 883 | a.in.font_addr = scr->scr_romfont; |
884 | | | 884 | |
885 | scr->scr_fontmaxcol = cfg->fbheight / fp->height; | | 885 | scr->scr_fontmaxcol = cfg->fbheight / fp->height; |
886 | scr->scr_fontbase = cfg->width + cfg->owidth; | | 886 | scr->scr_fontbase = cfg->width + cfg->owidth; |
887 | for (uc = fp->first; uc <= fp->last; uc++) { | | 887 | for (uc = fp->first; uc <= fp->last; uc++) { |
888 | a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) * | | 888 | a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) * |
889 | fp->width + scr->scr_fontbase; | | 889 | fp->width + scr->scr_fontbase; |
890 | a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) * | | 890 | a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) * |
891 | fp->height; | | 891 | fp->height; |
892 | a.in.index = uc; | | 892 | a.in.index = uc; |
893 | | | 893 | |
894 | (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); | | 894 | (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); |
895 | if (a.out.errno) { | | 895 | if (a.out.errno) { |
896 | aprint_error_dev(sc->sc_dev, "unpmv %d " | | 896 | aprint_error_dev(sc->sc_dev, "unpmv %d " |
897 | "returned %d\n", uc, a.out.errno); | | 897 | "returned %d\n", uc, a.out.errno); |
898 | return 0; | | 898 | return 0; |
899 | } | | 899 | } |
900 | } | | 900 | } |
901 | | | 901 | |
902 | free(scr->scr_romfont, M_DEVBUF); | | 902 | free(scr->scr_romfont, M_DEVBUF); |
903 | scr->scr_romfont = NULL; | | 903 | scr->scr_romfont = NULL; |
904 | } | | 904 | } |
905 | #endif | | 905 | #endif |
906 | | | 906 | |
907 | return 0; | | 907 | return 0; |
908 | } | | 908 | } |
909 | | | 909 | |
910 | /* | | 910 | /* |
911 | * Wrappers around STI code pointers | | 911 | * Wrappers around STI code pointers |
912 | */ | | 912 | */ |
913 | | | 913 | |
914 | int | | 914 | int |
915 | sti_init(struct sti_screen *scr, int mode) | | 915 | sti_init(struct sti_screen *scr, int mode) |
916 | { | | 916 | { |
917 | struct sti_rom *rom = scr->scr_rom; | | 917 | struct sti_rom *rom = scr->scr_rom; |
918 | struct { | | 918 | struct { |
919 | struct sti_initflags flags; | | 919 | struct sti_initflags flags; |
920 | struct sti_initin in; | | 920 | struct sti_initin in; |
921 | struct sti_einitin ein; | | 921 | struct sti_einitin ein; |
922 | struct sti_initout out; | | 922 | struct sti_initout out; |
923 | } a; | | 923 | } a; |
924 | | | 924 | |
925 | KASSERT(rom != NULL); | | 925 | KASSERT(rom != NULL); |
926 | memset(&a, 0, sizeof(a)); | | 926 | memset(&a, 0, sizeof(a)); |
927 | | | 927 | |
928 | a.flags.flags = STI_INITF_WAIT | STI_INITF_EBET; | | 928 | a.flags.flags = STI_INITF_WAIT | STI_INITF_EBET; |
929 | if ((mode & STI_TEXTMODE) != 0) { | | 929 | if ((mode & STI_TEXTMODE) != 0) { |
930 | a.flags.flags |= STI_INITF_TEXT | STI_INITF_CMB | | | 930 | a.flags.flags |= STI_INITF_TEXT | STI_INITF_CMB | |
931 | STI_INITF_PBET | STI_INITF_PBETI | STI_INITF_ICMT; | | 931 | STI_INITF_PBET | STI_INITF_PBETI | STI_INITF_ICMT; |
932 | } else { | | 932 | } else { |
933 | a.flags.flags |= STI_INITF_NTEXT; | | 933 | a.flags.flags |= STI_INITF_NTEXT; |
934 | } | | 934 | } |
935 | if ((mode & STI_CLEARSCR) != 0) | | 935 | if ((mode & STI_CLEARSCR) != 0) |
936 | a.flags.flags |= STI_INITF_CLEAR; | | 936 | a.flags.flags |= STI_INITF_CLEAR; |
937 | | | 937 | |
938 | a.in.text_planes = 1; | | 938 | a.in.text_planes = 1; |
939 | a.in.ext_in = &a.ein; | | 939 | a.in.ext_in = &a.ein; |
940 | | | 940 | |
941 | DPRINTF(("%s: init,%p(%x, %p, %p, %p)\n", | | 941 | DPRINTF(("%s: init,%p(%x, %p, %p, %p)\n", |
942 | device_xname(rom->rom_softc->sc_dev), rom->init, a.flags.flags, | | 942 | device_xname(rom->rom_softc->sc_dev), rom->init, a.flags.flags, |
943 | &a.in, &a.out, &scr->scr_cfg)); | | 943 | &a.in, &a.out, &scr->scr_cfg)); |
944 | | | 944 | |
945 | (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); | | 945 | (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); |
946 | | | 946 | |
947 | if (a.out.text_planes != a.in.text_planes) | | 947 | if (a.out.text_planes != a.in.text_planes) |
948 | return -1; /* not colliding with sti errno values */ | | 948 | return -1; /* not colliding with sti errno values */ |
949 | return a.out.errno; | | 949 | return a.out.errno; |
950 | } | | 950 | } |
951 | | | 951 | |
952 | int | | 952 | int |
953 | sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) | | 953 | sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) |
954 | { | | 954 | { |
955 | struct sti_rom *rom = scr->scr_rom; | | 955 | struct sti_rom *rom = scr->scr_rom; |
956 | struct { | | 956 | struct { |
957 | struct sti_inqconfflags flags; | | 957 | struct sti_inqconfflags flags; |
958 | struct sti_inqconfin in; | | 958 | struct sti_inqconfin in; |
959 | } a; | | 959 | } a; |
960 | | | 960 | |
961 | memset(&a, 0, sizeof(a)); | | 961 | memset(&a, 0, sizeof(a)); |
962 | | | 962 | |
963 | a.flags.flags = STI_INQCONFF_WAIT; | | 963 | a.flags.flags = STI_INQCONFF_WAIT; |
964 | (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); | | 964 | (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); |
965 | | | 965 | |
966 | return out->errno; | | 966 | return out->errno; |
967 | } | | 967 | } |
968 | | | 968 | |
969 | void | | 969 | void |
970 | sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w, | | 970 | sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w, |
971 | enum sti_bmove_funcs f) | | 971 | enum sti_bmove_funcs f) |
972 | { | | 972 | { |
973 | struct sti_rom *rom = scr->scr_rom; | | 973 | struct sti_rom *rom = scr->scr_rom; |
974 | struct { | | 974 | struct { |
975 | struct sti_blkmvflags flags; | | 975 | struct sti_blkmvflags flags; |
976 | struct sti_blkmvin in; | | 976 | struct sti_blkmvin in; |
977 | struct sti_blkmvout out; | | 977 | struct sti_blkmvout out; |
978 | } a; | | 978 | } a; |
979 | | | 979 | |
980 | memset(&a, 0, sizeof(a)); | | 980 | memset(&a, 0, sizeof(a)); |
981 | | | 981 | |
982 | a.flags.flags = STI_BLKMVF_WAIT; | | 982 | a.flags.flags = STI_BLKMVF_WAIT; |
983 | switch (f) { | | 983 | switch (f) { |
984 | case bmf_clear: | | 984 | case bmf_clear: |
985 | a.flags.flags |= STI_BLKMVF_CLR; | | 985 | a.flags.flags |= STI_BLKMVF_CLR; |
986 | a.in.bg_colour = STI_COLOUR_BLACK; | | 986 | a.in.bg_colour = STI_COLOUR_BLACK; |
987 | break; | | 987 | break; |
988 | case bmf_underline: | | 988 | case bmf_underline: |
989 | case bmf_copy: | | 989 | case bmf_copy: |
990 | a.in.fg_colour = STI_COLOUR_WHITE; | | 990 | a.in.fg_colour = STI_COLOUR_WHITE; |
991 | a.in.bg_colour = STI_COLOUR_BLACK; | | 991 | a.in.bg_colour = STI_COLOUR_BLACK; |
992 | break; | | 992 | break; |
993 | case bmf_invert: | | 993 | case bmf_invert: |
994 | a.flags.flags |= STI_BLKMVF_COLR; | | 994 | a.flags.flags |= STI_BLKMVF_COLR; |
995 | a.in.fg_colour = STI_COLOUR_BLACK; | | 995 | a.in.fg_colour = STI_COLOUR_BLACK; |
996 | a.in.bg_colour = STI_COLOUR_WHITE; | | 996 | a.in.bg_colour = STI_COLOUR_WHITE; |
997 | break; | | 997 | break; |
998 | } | | 998 | } |
999 | a.in.srcx = x1; | | 999 | a.in.srcx = x1; |
1000 | a.in.srcy = y1; | | 1000 | a.in.srcy = y1; |
1001 | a.in.dstx = x2; | | 1001 | a.in.dstx = x2; |
1002 | a.in.dsty = y2; | | 1002 | a.in.dsty = y2; |
1003 | a.in.height = h; | | 1003 | a.in.height = h; |
1004 | a.in.width = w; | | 1004 | a.in.width = w; |
1005 | | | 1005 | |
1006 | (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); | | 1006 | (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); |
1007 | #ifdef STIDEBUG | | 1007 | #ifdef STIDEBUG |
1008 | if (a.out.errno) | | 1008 | if (a.out.errno) |
1009 | printf("%s: blkmv returned %d\n", | | 1009 | printf("%s: blkmv returned %d\n", |
1010 | device_xname(rom->rom_softc->sc_dev), a.out.errno); | | 1010 | device_xname(rom->rom_softc->sc_dev), a.out.errno); |
1011 | #endif | | 1011 | #endif |
1012 | } | | 1012 | } |
1013 | | | 1013 | |
1014 | int | | 1014 | int |
1015 | sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) | | 1015 | sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) |
1016 | { | | 1016 | { |
1017 | struct sti_rom *rom = scr->scr_rom; | | 1017 | struct sti_rom *rom = scr->scr_rom; |
1018 | struct { | | 1018 | struct { |
1019 | struct sti_scmentflags flags; | | 1019 | struct sti_scmentflags flags; |
1020 | struct sti_scmentin in; | | 1020 | struct sti_scmentin in; |
1021 | struct sti_scmentout out; | | 1021 | struct sti_scmentout out; |
1022 | } a; | | 1022 | } a; |
1023 | | | 1023 | |
1024 | memset(&a, 0, sizeof(a)); | | 1024 | memset(&a, 0, sizeof(a)); |
1025 | | | 1025 | |
1026 | a.flags.flags = STI_SCMENTF_WAIT; | | 1026 | a.flags.flags = STI_SCMENTF_WAIT; |
1027 | a.in.entry = i; | | 1027 | a.in.entry = i; |
1028 | a.in.value = (r << 16) | (g << 8) | b; | | 1028 | a.in.value = (r << 16) | (g << 8) | b; |
1029 | | | 1029 | |
1030 | (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); | | 1030 | (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); |
1031 | | | 1031 | |
1032 | return a.out.errno; | | 1032 | return a.out.errno; |
1033 | } | | 1033 | } |
1034 | | | 1034 | |
1035 | /* | | 1035 | /* |
1036 | * wsdisplay accessops | | 1036 | * wsdisplay accessops |
1037 | */ | | 1037 | */ |
1038 | int | | 1038 | int |
1039 | sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) | | 1039 | sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) |
1040 | { | | 1040 | { |
1041 | struct sti_screen *scr = (struct sti_screen *)v; | | 1041 | struct sti_screen *scr = (struct sti_screen *)v; |
1042 | struct wsdisplay_fbinfo *wdf; | | 1042 | struct wsdisplay_fbinfo *wdf; |
1043 | struct wsdisplay_cmap *cmapp; | | 1043 | struct wsdisplay_cmap *cmapp; |
1044 | u_int mode, idx, count; | | 1044 | u_int mode, idx, count; |
1045 | int ret; | | 1045 | int ret; |
1046 | | | 1046 | |
1047 | ret = 0; | | 1047 | ret = 0; |
1048 | switch (cmd) { | | 1048 | switch (cmd) { |
1049 | case WSDISPLAYIO_GMODE: | | 1049 | case WSDISPLAYIO_GMODE: |
1050 | *(u_int *)data = scr->scr_wsmode; | | 1050 | *(u_int *)data = scr->scr_wsmode; |
1051 | break; | | 1051 | break; |
1052 | | | 1052 | |
1053 | case WSDISPLAYIO_SMODE: | | 1053 | case WSDISPLAYIO_SMODE: |
1054 | mode = *(u_int *)data; | | 1054 | mode = *(u_int *)data; |
1055 | switch (mode) { | | 1055 | switch (mode) { |
1056 | case WSDISPLAYIO_MODE_EMUL: | | 1056 | case WSDISPLAYIO_MODE_EMUL: |
1057 | if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL) | | 1057 | if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL) |
1058 | ret = sti_init(scr, STI_TEXTMODE); | | 1058 | ret = sti_init(scr, STI_TEXTMODE); |
1059 | break; | | 1059 | break; |
1060 | case WSDISPLAYIO_MODE_DUMBFB: | | 1060 | case WSDISPLAYIO_MODE_DUMBFB: |
1061 | if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) { | | 1061 | if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) { |
1062 | sti_init(scr, 0); | | 1062 | sti_init(scr, 0); |
1063 | if (scr->setupfb != NULL) | | 1063 | if (scr->setupfb != NULL) |
1064 | scr->setupfb(scr); | | 1064 | scr->setupfb(scr); |
1065 | else | | 1065 | else |
1066 | #if 0 | | 1066 | #if 0 |
1067 | ret = sti_init(scr, STI_FBMODE); | | 1067 | ret = sti_init(scr, STI_FBMODE); |
1068 | #else | | 1068 | #else |
1069 | ret = EINVAL; | | 1069 | ret = EINVAL; |
1070 | #endif | | 1070 | #endif |
1071 | } | | 1071 | } |
1072 | break; | | 1072 | break; |
1073 | case WSDISPLAYIO_MODE_MAPPED: | | 1073 | case WSDISPLAYIO_MODE_MAPPED: |
1074 | default: | | 1074 | default: |
1075 | ret = EINVAL; | | 1075 | ret = EINVAL; |
1076 | break; | | 1076 | break; |
1077 | } | | 1077 | } |
1078 | if (ret == 0) | | 1078 | if (ret == 0) |
1079 | scr->scr_wsmode = mode; | | 1079 | scr->scr_wsmode = mode; |
1080 | break; | | 1080 | break; |
1081 | | | 1081 | |
1082 | case WSDISPLAYIO_GTYPE: | | 1082 | case WSDISPLAYIO_GTYPE: |
1083 | *(u_int *)data = WSDISPLAY_TYPE_STI; | | 1083 | *(u_int *)data = WSDISPLAY_TYPE_STI; |
1084 | break; | | 1084 | break; |
1085 | | | 1085 | |
1086 | case WSDISPLAYIO_GINFO: | | 1086 | case WSDISPLAYIO_GINFO: |
1087 | wdf = (struct wsdisplay_fbinfo *)data; | | 1087 | wdf = (struct wsdisplay_fbinfo *)data; |
1088 | wdf->height = scr->scr_cfg.scr_height; | | 1088 | wdf->height = scr->scr_cfg.scr_height; |
1089 | wdf->width = scr->scr_cfg.scr_width; | | 1089 | wdf->width = scr->scr_cfg.scr_width; |
1090 | wdf->depth = scr->scr_bpp; | | 1090 | wdf->depth = scr->scr_bpp; |
1091 | if (scr->putcmap == NULL || scr->scr_bpp > 8) | | 1091 | if (scr->putcmap == NULL || scr->scr_bpp > 8) |
1092 | wdf->cmsize = 0; | | 1092 | wdf->cmsize = 0; |
1093 | else | | 1093 | else |
1094 | wdf->cmsize = STI_NCMAP; | | 1094 | wdf->cmsize = STI_NCMAP; |
1095 | break; | | 1095 | break; |
1096 | | | 1096 | |
1097 | case WSDISPLAYIO_LINEBYTES: | | 1097 | case WSDISPLAYIO_LINEBYTES: |
1098 | if (scr->scr_bpp > 8) | | 1098 | if (scr->scr_bpp > 8) |
1099 | *(u_int *)data = scr->scr_cfg.fb_width * 4; | | 1099 | *(u_int *)data = scr->scr_cfg.fb_width * 4; |
1100 | else | | 1100 | else |
1101 | *(u_int *)data = scr->scr_cfg.fb_width; | | 1101 | *(u_int *)data = scr->scr_cfg.fb_width; |
1102 | break; | | 1102 | break; |
1103 | | | 1103 | |
1104 | case WSDISPLAYIO_GETCMAP: | | 1104 | case WSDISPLAYIO_GETCMAP: |
1105 | if (scr->putcmap == NULL || scr->scr_bpp > 8) | | 1105 | if (scr->putcmap == NULL || scr->scr_bpp > 8) |
1106 | return ENODEV; | | 1106 | return ENODEV; |
1107 | cmapp = (struct wsdisplay_cmap *)data; | | 1107 | cmapp = (struct wsdisplay_cmap *)data; |
1108 | idx = cmapp->index; | | 1108 | idx = cmapp->index; |
1109 | count = cmapp->count; | | 1109 | count = cmapp->count; |
1110 | if (idx >= STI_NCMAP || count > STI_NCMAP - idx) | | 1110 | if (idx >= STI_NCMAP || count > STI_NCMAP - idx) |
1111 | return EINVAL; | | 1111 | return EINVAL; |
1112 | if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count))) | | 1112 | if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count))) |
1113 | break; | | 1113 | break; |
1114 | if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count))) | | 1114 | if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count))) |
1115 | break; | | 1115 | break; |
1116 | if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count))) | | 1116 | if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count))) |
1117 | break; | | 1117 | break; |
1118 | break; | | 1118 | break; |
1119 | | | 1119 | |
1120 | case WSDISPLAYIO_PUTCMAP: | | 1120 | case WSDISPLAYIO_PUTCMAP: |
1121 | if (scr->putcmap == NULL || scr->scr_bpp > 8) | | 1121 | if (scr->putcmap == NULL || scr->scr_bpp > 8) |
1122 | return ENODEV; | | 1122 | return ENODEV; |
1123 | if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL) { | | 1123 | if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL) { |
1124 | /* | | 1124 | /* |
1125 | * The hardware palette settings are handled by | | 1125 | * The hardware palette settings are handled by |
1126 | * the STI ROM in STI_TEXTMODE and changing cmap | | 1126 | * the STI ROM in STI_TEXTMODE and changing cmap |
1127 | * could cause mangled text colors at least on CRX. | | 1127 | * could cause mangled text colors at least on CRX. |
1128 | * Updating CMAP in EMUL mode isn't expected anyway | | 1128 | * Updating CMAP in EMUL mode isn't expected anyway |
1129 | * so just ignore it. | | 1129 | * so just ignore it. |
1130 | */ | | 1130 | */ |
1131 | return 0; | | 1131 | return 0; |
1132 | } | | 1132 | } |
1133 | cmapp = (struct wsdisplay_cmap *)data; | | 1133 | cmapp = (struct wsdisplay_cmap *)data; |
1134 | idx = cmapp->index; | | 1134 | idx = cmapp->index; |
1135 | count = cmapp->count; | | 1135 | count = cmapp->count; |
1136 | if (idx >= STI_NCMAP || count > STI_NCMAP - idx) | | 1136 | if (idx >= STI_NCMAP || count > STI_NCMAP - idx) |
1137 | return EINVAL; | | 1137 | return EINVAL; |
1138 | if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count))) | | 1138 | if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count))) |
1139 | break; | | 1139 | break; |
1140 | if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count))) | | 1140 | if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count))) |
1141 | break; | | 1141 | break; |
1142 | if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count))) | | 1142 | if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count))) |
1143 | break; | | 1143 | break; |
1144 | ret = scr->putcmap(scr, idx, count); | | 1144 | ret = scr->putcmap(scr, idx, count); |
1145 | break; | | 1145 | break; |
1146 | | | 1146 | |
1147 | case WSDISPLAYIO_SVIDEO: | | 1147 | case WSDISPLAYIO_SVIDEO: |
1148 | case WSDISPLAYIO_GVIDEO: | | 1148 | case WSDISPLAYIO_GVIDEO: |
1149 | case WSDISPLAYIO_GCURPOS: | | 1149 | case WSDISPLAYIO_GCURPOS: |
1150 | case WSDISPLAYIO_SCURPOS: | | 1150 | case WSDISPLAYIO_SCURPOS: |
1151 | case WSDISPLAYIO_GCURMAX: | | 1151 | case WSDISPLAYIO_GCURMAX: |
1152 | case WSDISPLAYIO_GCURSOR: | | 1152 | case WSDISPLAYIO_GCURSOR: |
1153 | case WSDISPLAYIO_SCURSOR: | | 1153 | case WSDISPLAYIO_SCURSOR: |
1154 | default: | | 1154 | default: |
1155 | return ENOTTY; /* not supported yet */ | | 1155 | return ENOTTY; /* not supported yet */ |
1156 | } | | 1156 | } |
1157 | | | 1157 | |
1158 | return ret; | | 1158 | return ret; |
1159 | } | | 1159 | } |
1160 | | | 1160 | |
1161 | paddr_t | | 1161 | paddr_t |
1162 | sti_mmap(void *v, void *vs, off_t offset, int prot) | | 1162 | sti_mmap(void *v, void *vs, off_t offset, int prot) |
1163 | { | | 1163 | { |
1164 | struct sti_screen *scr = (struct sti_screen *)v; | | 1164 | struct sti_screen *scr = (struct sti_screen *)v; |
1165 | struct sti_rom *rom = scr->scr_rom; | | 1165 | struct sti_rom *rom = scr->scr_rom; |
1166 | paddr_t pa; | | 1166 | paddr_t pa; |
1167 | | | 1167 | |
1168 | if ((offset & PAGE_MASK) != 0) | | 1168 | if ((offset & PAGE_MASK) != 0) |
1169 | return -1; | | 1169 | return -1; |
1170 | | | 1170 | |
1171 | if (offset < 0 || offset >= scr->fblen) | | 1171 | if (offset < 0 || offset >= scr->fblen) |
1172 | return -1; | | 1172 | return -1; |
1173 | | | 1173 | |
1174 | if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) | | 1174 | if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) |
1175 | return -1; | | 1175 | return -1; |
1176 | | | 1176 | |
1177 | pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot, | | 1177 | pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot, |
1178 | BUS_SPACE_MAP_LINEAR); | | 1178 | BUS_SPACE_MAP_LINEAR); |
1179 | | | 1179 | |
1180 | if (pa == -1) | | 1180 | if (pa == -1) |
1181 | pa = scr->fbaddr + offset; | | 1181 | pa = scr->fbaddr + offset; |
1182 | | | 1182 | |
1183 | return pa; | | 1183 | return pa; |
1184 | } | | 1184 | } |
1185 | | | 1185 | |
1186 | int | | 1186 | int |
1187 | sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, | | 1187 | sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, |
1188 | int *cxp, int *cyp, long *defattr) | | 1188 | int *cxp, int *cyp, long *defattr) |
1189 | { | | 1189 | { |
1190 | struct sti_screen *scr = (struct sti_screen *)v; | | 1190 | struct sti_screen *scr = (struct sti_screen *)v; |
1191 | | | 1191 | |
1192 | if (scr->scr_nscreens > 0) | | 1192 | if (scr->scr_nscreens > 0) |
1193 | return ENOMEM; | | 1193 | return ENOMEM; |
1194 | | | 1194 | |
1195 | *cookiep = scr; | | 1195 | *cookiep = scr; |
1196 | *cxp = 0; | | 1196 | *cxp = 0; |
1197 | *cyp = 0; | | 1197 | *cyp = 0; |
1198 | sti_alloc_attr(scr, 0, 0, 0, defattr); | | 1198 | sti_alloc_attr(scr, 0, 0, 0, defattr); |
1199 | scr->scr_nscreens++; | | 1199 | scr->scr_nscreens++; |
1200 | return 0; | | 1200 | return 0; |
1201 | } | | 1201 | } |
1202 | | | 1202 | |
1203 | void | | 1203 | void |
1204 | sti_free_screen(void *v, void *cookie) | | 1204 | sti_free_screen(void *v, void *cookie) |
1205 | { | | 1205 | { |
1206 | struct sti_screen *scr = (struct sti_screen *)v; | | 1206 | struct sti_screen *scr = (struct sti_screen *)v; |
1207 | | | 1207 | |
1208 | scr->scr_nscreens--; | | 1208 | scr->scr_nscreens--; |
1209 | } | | 1209 | } |
1210 | | | 1210 | |
1211 | int | | 1211 | int |
1212 | sti_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), | | 1212 | sti_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), |
1213 | void *cbarg) | | 1213 | void *cbarg) |
1214 | { | | 1214 | { |
1215 | #if 0 | | 1215 | #if 0 |
1216 | struct sti_screen *scr = (struct sti_screen *)v; | | 1216 | struct sti_screen *scr = (struct sti_screen *)v; |
1217 | #endif | | 1217 | #endif |
1218 | | | 1218 | |
1219 | return 0; | | 1219 | return 0; |
1220 | } | | 1220 | } |
1221 | | | 1221 | |
1222 | int | | 1222 | int |
1223 | sti_load_font(void *v, void *cookie, struct wsdisplay_font *font) | | 1223 | sti_load_font(void *v, void *cookie, struct wsdisplay_font *font) |
1224 | { | | 1224 | { |
1225 | #if 0 | | 1225 | #if 0 |
1226 | struct sti_screen *scr = (struct sti_screen *)v; | | 1226 | struct sti_screen *scr = (struct sti_screen *)v; |
1227 | #endif | | 1227 | #endif |
1228 | | | 1228 | |
1229 | return -1; | | 1229 | return -1; |
1230 | } | | 1230 | } |
1231 | | | 1231 | |
1232 | /* | | 1232 | /* |
1233 | * wsdisplay emulops | | 1233 | * wsdisplay emulops |
1234 | */ | | 1234 | */ |
1235 | void | | 1235 | void |
1236 | sti_cursor(void *v, int on, int row, int col) | | 1236 | sti_cursor(void *v, int on, int row, int col) |
1237 | { | | 1237 | { |
1238 | struct sti_screen *scr = (struct sti_screen *)v; | | 1238 | struct sti_screen *scr = (struct sti_screen *)v; |
1239 | struct sti_font *fp = &scr->scr_curfont; | | 1239 | struct sti_font *fp = &scr->scr_curfont; |
1240 | | | 1240 | |
1241 | sti_bmove(scr, | | 1241 | sti_bmove(scr, |
1242 | col * fp->width, row * fp->height, | | 1242 | col * fp->width, row * fp->height, |
1243 | col * fp->width, row * fp->height, | | 1243 | col * fp->width, row * fp->height, |
1244 | fp->height, fp->width, bmf_invert); | | 1244 | fp->height, fp->width, bmf_invert); |
1245 | } | | 1245 | } |
1246 | | | 1246 | |
1247 | /* | | 1247 | /* |
1248 | * ISO 8859-1 part of Unicode to HP Roman font index conversion array. | | 1248 | * ISO 8859-1 part of Unicode to HP Roman font index conversion array. |
1249 | */ | | 1249 | */ |
1250 | static const uint8_t | | 1250 | static const uint8_t |
1251 | sti_unitoroman[0x100 - 0xa0] = { | | 1251 | sti_unitoroman[0x100 - 0xa0] = { |
1252 | 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd, | | 1252 | 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd, |
1253 | 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0, | | 1253 | 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0, |
1254 | | | 1254 | |
1255 | 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2, | | 1255 | 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2, |
1256 | 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9, | | 1256 | 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9, |
1257 | | | 1257 | |
1258 | 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4, | | 1258 | 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4, |
1259 | 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7, | | 1259 | 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7, |
1260 | | | 1260 | |
1261 | 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0, | | 1261 | 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0, |
1262 | 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde, | | 1262 | 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde, |
1263 | | | 1263 | |
1264 | 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5, | | 1264 | 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5, |
1265 | 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd, | | 1265 | 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd, |
1266 | | | 1266 | |
1267 | 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0, | | 1267 | 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0, |
1268 | 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef | | 1268 | 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef |
1269 | }; | | 1269 | }; |
1270 | | | 1270 | |
1271 | int | | 1271 | int |
1272 | sti_mapchar(void *v, int uni, u_int *index) | | 1272 | sti_mapchar(void *v, int uni, u_int *index) |
1273 | { | | 1273 | { |
1274 | struct sti_screen *scr = (struct sti_screen *)v; | | 1274 | struct sti_screen *scr = (struct sti_screen *)v; |
1275 | struct sti_font *fp = &scr->scr_curfont; | | 1275 | struct sti_font *fp = &scr->scr_curfont; |
1276 | int c; | | 1276 | int c; |
1277 | | | 1277 | |
1278 | switch (fp->type) { | | 1278 | switch (fp->type) { |
1279 | case STI_FONT_HPROMAN8: | | 1279 | case STI_FONT_HPROMAN8: |
1280 | if (uni >= 0x80 && uni < 0xa0) | | 1280 | if (uni >= 0x80 && uni < 0xa0) |
1281 | c = -1; | | 1281 | c = -1; |
1282 | else if (uni >= 0xa0 && uni < 0x100) { | | 1282 | else if (uni >= 0xa0 && uni < 0x100) { |
1283 | c = (int)sti_unitoroman[uni - 0xa0]; | | 1283 | c = (int)sti_unitoroman[uni - 0xa0]; |
1284 | if (c == 0) | | 1284 | if (c == 0) |
1285 | c = -1; | | 1285 | c = -1; |
1286 | } else | | 1286 | } else |
1287 | c = uni; | | 1287 | c = uni; |
1288 | break; | | 1288 | break; |
1289 | default: | | 1289 | default: |
1290 | c = uni; | | 1290 | c = uni; |
1291 | break; | | 1291 | break; |
1292 | } | | 1292 | } |
1293 | | | 1293 | |
1294 | if (c == -1 || c < fp->first || c > fp->last) { | | 1294 | if (c == -1 || c < fp->first || c > fp->last) { |
1295 | *index = ' '; | | 1295 | *index = ' '; |
1296 | return 0; | | 1296 | return 0; |
1297 | } | | 1297 | } |
1298 | | | 1298 | |
1299 | *index = c; | | 1299 | *index = c; |
1300 | return 5; | | 1300 | return 5; |
1301 | } | | 1301 | } |
1302 | | | 1302 | |
1303 | void | | 1303 | void |
1304 | sti_putchar(void *v, int row, int col, u_int uc, long attr) | | 1304 | sti_putchar(void *v, int row, int col, u_int uc, long attr) |
1305 | { | | 1305 | { |
1306 | struct sti_screen *scr = (struct sti_screen *)v; | | 1306 | struct sti_screen *scr = (struct sti_screen *)v; |
1307 | struct sti_rom *rom = scr->scr_rom; | | 1307 | struct sti_rom *rom = scr->scr_rom; |
1308 | struct sti_font *fp = &scr->scr_curfont; | | 1308 | struct sti_font *fp = &scr->scr_curfont; |
1309 | int bg, fg; | | 1309 | int bg, fg; |
1310 | | | 1310 | |
1311 | fg = WSATTR_UNPACK_FG(attr); | | 1311 | fg = WSATTR_UNPACK_FG(attr); |
1312 | bg = WSATTR_UNPACK_BG(attr); | | 1312 | bg = WSATTR_UNPACK_BG(attr); |
1313 | | | 1313 | |
1314 | if (scr->scr_romfont != NULL) { | | 1314 | if (scr->scr_romfont != NULL) { |
1315 | /* | | 1315 | /* |
1316 | * Font is in memory, use unpmv | | 1316 | * Font is in memory, use unpmv |
1317 | */ | | 1317 | */ |
1318 | struct { | | 1318 | struct { |
1319 | struct sti_unpmvflags flags; | | 1319 | struct sti_unpmvflags flags; |
1320 | struct sti_unpmvin in; | | 1320 | struct sti_unpmvin in; |
1321 | struct sti_unpmvout out; | | 1321 | struct sti_unpmvout out; |
1322 | } a; | | 1322 | } a; |
1323 | | | 1323 | |
1324 | memset(&a, 0, sizeof(a)); | | 1324 | memset(&a, 0, sizeof(a)); |
1325 | | | 1325 | |
1326 | a.flags.flags = STI_UNPMVF_WAIT; | | 1326 | a.flags.flags = STI_UNPMVF_WAIT; |
1327 | a.in.fg_colour = fg; | | 1327 | a.in.fg_colour = fg; |
1328 | a.in.bg_colour = bg; | | 1328 | a.in.bg_colour = bg; |
1329 | a.in.x = col * fp->width; | | 1329 | a.in.x = col * fp->width; |
1330 | a.in.y = row * fp->height; | | 1330 | a.in.y = row * fp->height; |
1331 | a.in.font_addr = scr->scr_romfont; | | 1331 | a.in.font_addr = scr->scr_romfont; |
1332 | a.in.index = uc; | | 1332 | a.in.index = uc; |
1333 | | | 1333 | |
1334 | (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); | | 1334 | (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); |
1335 | } else { | | 1335 | } else { |
1336 | /* | | 1336 | /* |
1337 | * Font is in frame buffer, use blkmv | | 1337 | * Font is in frame buffer, use blkmv |
1338 | */ | | 1338 | */ |
1339 | struct { | | 1339 | struct { |
1340 | struct sti_blkmvflags flags; | | 1340 | struct sti_blkmvflags flags; |
1341 | struct sti_blkmvin in; | | 1341 | struct sti_blkmvin in; |
1342 | struct sti_blkmvout out; | | 1342 | struct sti_blkmvout out; |
1343 | } a; | | 1343 | } a; |
1344 | | | 1344 | |
1345 | memset(&a, 0, sizeof(a)); | | 1345 | memset(&a, 0, sizeof(a)); |
1346 | | | 1346 | |
1347 | a.flags.flags = STI_BLKMVF_WAIT; | | 1347 | a.flags.flags = STI_BLKMVF_WAIT; |
1348 | a.in.fg_colour = fg; | | 1348 | a.in.fg_colour = fg; |
1349 | a.in.bg_colour = bg; | | 1349 | a.in.bg_colour = bg; |
1350 | | | 1350 | |
1351 | a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) * | | 1351 | a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) * |
1352 | fp->width + scr->scr_fontbase; | | 1352 | fp->width + scr->scr_fontbase; |
1353 | a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) * | | 1353 | a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) * |
1354 | fp->height; | | 1354 | fp->height; |
1355 | a.in.dstx = col * fp->width; | | 1355 | a.in.dstx = col * fp->width; |
1356 | a.in.dsty = row * fp->height; | | 1356 | a.in.dsty = row * fp->height; |
1357 | a.in.height = fp->height; | | 1357 | a.in.height = fp->height; |
1358 | a.in.width = fp->width; | | 1358 | a.in.width = fp->width; |
1359 | | | 1359 | |
1360 | (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); | | 1360 | (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); |
1361 | } | | 1361 | } |
1362 | } | | 1362 | } |
1363 | | | 1363 | |
1364 | void | | 1364 | void |
1365 | sti_copycols(void *v, int row, int srccol, int dstcol, int ncols) | | 1365 | sti_copycols(void *v, int row, int srccol, int dstcol, int ncols) |
1366 | { | | 1366 | { |
1367 | struct sti_screen *scr = (struct sti_screen *)v; | | 1367 | struct sti_screen *scr = (struct sti_screen *)v; |
1368 | struct sti_font *fp = &scr->scr_curfont; | | 1368 | struct sti_font *fp = &scr->scr_curfont; |
1369 | | | 1369 | |
1370 | sti_bmove(scr, | | 1370 | sti_bmove(scr, |
1371 | srccol * fp->width, row * fp->height, | | 1371 | srccol * fp->width, row * fp->height, |
1372 | dstcol * fp->width, row * fp->height, | | 1372 | dstcol * fp->width, row * fp->height, |
1373 | fp->height, ncols * fp->width, bmf_copy); | | 1373 | fp->height, ncols * fp->width, bmf_copy); |
1374 | } | | 1374 | } |
1375 | | | 1375 | |
1376 | void | | 1376 | void |
1377 | sti_erasecols(void *v, int row, int startcol, int ncols, long attr) | | 1377 | sti_erasecols(void *v, int row, int startcol, int ncols, long attr) |
1378 | { | | 1378 | { |
1379 | struct sti_screen *scr = (struct sti_screen *)v; | | 1379 | struct sti_screen *scr = (struct sti_screen *)v; |
1380 | struct sti_font *fp = &scr->scr_curfont; | | 1380 | struct sti_font *fp = &scr->scr_curfont; |
1381 | | | 1381 | |
1382 | sti_bmove(scr, | | 1382 | sti_bmove(scr, |
1383 | startcol * fp->width, row * fp->height, | | 1383 | startcol * fp->width, row * fp->height, |
1384 | startcol * fp->width, row * fp->height, | | 1384 | startcol * fp->width, row * fp->height, |
1385 | fp->height, ncols * fp->width, bmf_clear); | | 1385 | fp->height, ncols * fp->width, bmf_clear); |
1386 | } | | 1386 | } |
1387 | | | 1387 | |
1388 | void | | 1388 | void |
1389 | sti_copyrows(void *v, int srcrow, int dstrow, int nrows) | | 1389 | sti_copyrows(void *v, int srcrow, int dstrow, int nrows) |
1390 | { | | 1390 | { |
1391 | struct sti_screen *scr = (struct sti_screen *)v; | | 1391 | struct sti_screen *scr = (struct sti_screen *)v; |
1392 | struct sti_font *fp = &scr->scr_curfont; | | 1392 | struct sti_font *fp = &scr->scr_curfont; |
1393 | | | 1393 | |
1394 | sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height, | | 1394 | sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height, |
1395 | nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy); | | 1395 | nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy); |
1396 | } | | 1396 | } |
1397 | | | 1397 | |
1398 | void | | 1398 | void |
1399 | sti_eraserows(void *v, int srcrow, int nrows, long attr) | | 1399 | sti_eraserows(void *v, int srcrow, int nrows, long attr) |
1400 | { | | 1400 | { |
1401 | struct sti_screen *scr = (struct sti_screen *)v; | | 1401 | struct sti_screen *scr = (struct sti_screen *)v; |
1402 | struct sti_font *fp = &scr->scr_curfont; | | 1402 | struct sti_font *fp = &scr->scr_curfont; |
1403 | | | 1403 | |
1404 | sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height, | | 1404 | sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height, |
1405 | nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear); | | 1405 | nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear); |
1406 | } | | 1406 | } |
1407 | | | 1407 | |
1408 | int | | 1408 | int |
1409 | sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr) | | 1409 | sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr) |
1410 | { | | 1410 | { |
1411 | #if 0 | | 1411 | #if 0 |
1412 | struct sti_screen *scr = (struct sti_screen *)v; | | 1412 | struct sti_screen *scr = (struct sti_screen *)v; |
1413 | #endif | | 1413 | #endif |
1414 | | | 1414 | |
1415 | if ((flags & (WSATTR_HILIT | WSATTR_BLINK | | | 1415 | if ((flags & (WSATTR_HILIT | WSATTR_BLINK | |
1416 | WSATTR_UNDERLINE | WSATTR_WSCOLORS)) != 0) | | 1416 | WSATTR_UNDERLINE | WSATTR_WSCOLORS)) != 0) |
1417 | return EINVAL; | | 1417 | return EINVAL; |
1418 | if ((flags & WSATTR_REVERSE) != 0) { | | 1418 | if ((flags & WSATTR_REVERSE) != 0) { |
1419 | fg = STI_COLOUR_BLACK; | | 1419 | fg = STI_COLOUR_BLACK; |
1420 | bg = STI_COLOUR_WHITE; | | 1420 | bg = STI_COLOUR_WHITE; |
1421 | } else { | | 1421 | } else { |
1422 | fg = STI_COLOUR_WHITE; | | 1422 | fg = STI_COLOUR_WHITE; |
1423 | bg = STI_COLOUR_BLACK; | | 1423 | bg = STI_COLOUR_BLACK; |
1424 | } | | 1424 | } |
1425 | | | 1425 | |
1426 | *pattr = WSATTR_PACK(fg, bg, flags); | | 1426 | *pattr = WSATTR_PACK(fg, bg, flags); |
1427 | return 0; | | 1427 | return 0; |
1428 | } | | 1428 | } |
1429 | | | 1429 | |
1430 | #ifdef hp300 /* XXX */ | | | |
1431 | /* | | 1430 | /* |
1432 | * Early console support. Only used on hp300. | | 1431 | * Early console support. Only used on hp300, currently |
1433 | */ | | 1432 | */ |
1434 | int | | 1433 | int |
1435 | sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt, | | 1434 | sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt, |
1436 | bus_addr_t *bases, u_int codebase) | | 1435 | bus_addr_t *bases, u_int codebase) |
1437 | { | | 1436 | { |
1438 | bus_space_handle_t romh; | | 1437 | bus_space_handle_t romh; |
1439 | u_int romend; | | 1438 | u_int romend; |
1440 | int error; | | 1439 | int error; |
1441 | long defattr; | | 1440 | long defattr; |
1442 | | | 1441 | |
1443 | if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0) | | 1442 | if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0) |
1444 | return error; | | 1443 | return error; |
1445 | | | 1444 | |
1446 | /* | | 1445 | /* |
1447 | * Compute real PROM size | | 1446 | * Compute real PROM size |
1448 | */ | | 1447 | */ |
1449 | romend = sti_rom_size(memt, romh); | | 1448 | romend = sti_rom_size(memt, romh); |
1450 | | | 1449 | |
1451 | bus_space_unmap(memt, romh, PAGE_SIZE); | | 1450 | bus_space_unmap(memt, romh, PAGE_SIZE); |
1452 | | | 1451 | |
1453 | if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0) | | 1452 | if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0) |
1454 | return error; | | 1453 | return error; |
1455 | | | 1454 | |
1456 | bases[0] = romh; | | 1455 | bases[0] = romh; |
1457 | if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0) | | 1456 | if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0) |
1458 | return -1; | | 1457 | return -1; |
1459 | scr->scr_rom = rom; | | 1458 | scr->scr_rom = rom; |
1460 | if (sti_screen_setup(scr, STI_CLEARSCR) != 0) | | 1459 | if (sti_screen_setup(scr, STI_CLEARSCR) != 0) |
1461 | return -1; | | 1460 | return -1; |
1462 | | | 1461 | |
1463 | sti_alloc_attr(scr, 0, 0, 0, &defattr); | | 1462 | sti_alloc_attr(scr, 0, 0, 0, &defattr); |
1464 | wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr); | | 1463 | wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr); |
1465 | | | 1464 | |
1466 | return 0; | | 1465 | return 0; |
1467 | } | | 1466 | } |
1468 | #endif | | | |
1469 | | | 1467 | |
1470 | int | | 1468 | int |
1471 | ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count) | | 1469 | ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count) |
1472 | { | | 1470 | { |
1473 | int i, ret; | | 1471 | int i, ret; |
1474 | | | 1472 | |
1475 | for (i = idx + count - 1; i >= (int)idx; i--) | | 1473 | for (i = idx + count - 1; i >= (int)idx; i--) |
1476 | if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], | | 1474 | if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], |
1477 | scr->scr_gcmap[i], scr->scr_bcmap[i]))) | | 1475 | scr->scr_gcmap[i], scr->scr_bcmap[i]))) |
1478 | return EINVAL; | | 1476 | return EINVAL; |
1479 | | | 1477 | |
1480 | return 0; | | 1478 | return 0; |
1481 | } | | 1479 | } |
1482 | | | 1480 | |
1483 | #ifndef SMALL_KERNEL | | 1481 | #ifndef SMALL_KERNEL |
1484 | | | 1482 | |
1485 | void ngle_setup_hw(bus_space_tag_t, bus_space_handle_t); | | 1483 | void ngle_setup_hw(bus_space_tag_t, bus_space_handle_t); |
1486 | void ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t); | | 1484 | void ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t); |
1487 | void ngle_setup_attr_planes(struct sti_screen *scr); | | 1485 | void ngle_setup_attr_planes(struct sti_screen *scr); |
1488 | void ngle_setup_bt458(struct sti_screen *scr); | | 1486 | void ngle_setup_bt458(struct sti_screen *scr); |
1489 | | | 1487 | |
1490 | #define ngle_bt458_write(memt, memh, r, v) \ | | 1488 | #define ngle_bt458_write(memt, memh, r, v) \ |
1491 | bus_space_write_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24) | | 1489 | bus_space_write_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24) |
1492 | | | 1490 | |
1493 | void | | 1491 | void |
1494 | ngle_artist_setupfb(struct sti_screen *scr) | | 1492 | ngle_artist_setupfb(struct sti_screen *scr) |
1495 | { | | 1493 | { |
1496 | struct sti_rom *rom = scr->scr_rom; | | 1494 | struct sti_rom *rom = scr->scr_rom; |
1497 | bus_space_tag_t memt = rom->memt; | | 1495 | bus_space_tag_t memt = rom->memt; |
1498 | bus_space_handle_t memh = rom->regh[2]; | | 1496 | bus_space_handle_t memh = rom->regh[2]; |
1499 | | | 1497 | |
1500 | ngle_setup_bt458(scr); | | 1498 | ngle_setup_bt458(scr); |
1501 | | | 1499 | |
1502 | ngle_setup_hw(memt, memh); | | 1500 | ngle_setup_hw(memt, memh); |
1503 | ngle_setup_fb(memt, memh, scr->reg10_value); | | 1501 | ngle_setup_fb(memt, memh, scr->reg10_value); |
1504 | | | 1502 | |
1505 | ngle_setup_attr_planes(scr); | | 1503 | ngle_setup_attr_planes(scr); |
1506 | | | 1504 | |
1507 | ngle_setup_hw(memt, memh); | | 1505 | ngle_setup_hw(memt, memh); |
1508 | bus_space_write_4(memt, memh, NGLE_REG_21, | | 1506 | bus_space_write_4(memt, memh, NGLE_REG_21, |
1509 | bus_space_read_4(memt, memh, NGLE_REG_21) | 0x0a000000); | | 1507 | bus_space_read_4(memt, memh, NGLE_REG_21) | 0x0a000000); |
1510 | bus_space_write_4(memt, memh, NGLE_REG_27, | | 1508 | bus_space_write_4(memt, memh, NGLE_REG_27, |
1511 | bus_space_read_4(memt, memh, NGLE_REG_27) | 0x00800000); | | 1509 | bus_space_read_4(memt, memh, NGLE_REG_27) | 0x00800000); |
1512 | } | | 1510 | } |
1513 | | | 1511 | |
1514 | void | | 1512 | void |
1515 | ngle_elk_setupfb(struct sti_screen *scr) | | 1513 | ngle_elk_setupfb(struct sti_screen *scr) |
1516 | { | | 1514 | { |
1517 | struct sti_rom *rom = scr->scr_rom; | | 1515 | struct sti_rom *rom = scr->scr_rom; |
1518 | bus_space_tag_t memt = rom->memt; | | 1516 | bus_space_tag_t memt = rom->memt; |
1519 | bus_space_handle_t memh = rom->regh[2]; | | 1517 | bus_space_handle_t memh = rom->regh[2]; |
1520 | | | 1518 | |
1521 | ngle_setup_bt458(scr); | | 1519 | ngle_setup_bt458(scr); |
1522 | | | 1520 | |
1523 | ngle_setup_hw(memt, memh); | | 1521 | ngle_setup_hw(memt, memh); |
1524 | ngle_setup_fb(memt, memh, scr->reg10_value); | | 1522 | ngle_setup_fb(memt, memh, scr->reg10_value); |
1525 | | | 1523 | |
1526 | ngle_setup_attr_planes(scr); | | 1524 | ngle_setup_attr_planes(scr); |
1527 | | | 1525 | |
1528 | ngle_setup_hw(memt, memh); | | 1526 | ngle_setup_hw(memt, memh); |
1529 | /* enable overlay planes in Bt458 command register */ | | 1527 | /* enable overlay planes in Bt458 command register */ |
1530 | ngle_bt458_write(memt, memh, 0x0c, 0x06); | | 1528 | ngle_bt458_write(memt, memh, 0x0c, 0x06); |
1531 | ngle_bt458_write(memt, memh, 0x0e, 0x43); | | 1529 | ngle_bt458_write(memt, memh, 0x0e, 0x43); |
1532 | } | | 1530 | } |
1533 | | | 1531 | |
1534 | void | | 1532 | void |
1535 | ngle_timber_setupfb(struct sti_screen *scr) | | 1533 | ngle_timber_setupfb(struct sti_screen *scr) |
1536 | { | | 1534 | { |
1537 | struct sti_rom *rom = scr->scr_rom; | | 1535 | struct sti_rom *rom = scr->scr_rom; |
1538 | bus_space_tag_t memt = rom->memt; | | 1536 | bus_space_tag_t memt = rom->memt; |
1539 | bus_space_handle_t memh = rom->regh[2]; | | 1537 | bus_space_handle_t memh = rom->regh[2]; |
1540 | | | 1538 | |
1541 | ngle_setup_bt458(scr); | | 1539 | ngle_setup_bt458(scr); |
1542 | | | 1540 | |
1543 | ngle_setup_hw(memt, memh); | | 1541 | ngle_setup_hw(memt, memh); |
1544 | /* enable overlay planes in Bt458 command register */ | | 1542 | /* enable overlay planes in Bt458 command register */ |
1545 | ngle_bt458_write(memt, memh, 0x0c, 0x06); | | 1543 | ngle_bt458_write(memt, memh, 0x0c, 0x06); |
1546 | ngle_bt458_write(memt, memh, 0x0e, 0x43); | | 1544 | ngle_bt458_write(memt, memh, 0x0e, 0x43); |
1547 | } | | 1545 | } |
1548 | | | 1546 | |
1549 | void | | 1547 | void |
1550 | ngle_setup_bt458(struct sti_screen *scr) | | 1548 | ngle_setup_bt458(struct sti_screen *scr) |
1551 | { | | 1549 | { |
1552 | struct sti_rom *rom = scr->scr_rom; | | 1550 | struct sti_rom *rom = scr->scr_rom; |
1553 | bus_space_tag_t memt = rom->memt; | | 1551 | bus_space_tag_t memt = rom->memt; |
1554 | bus_space_handle_t memh = rom->regh[2]; | | 1552 | bus_space_handle_t memh = rom->regh[2]; |
1555 | | | 1553 | |
1556 | ngle_setup_hw(memt, memh); | | 1554 | ngle_setup_hw(memt, memh); |
1557 | /* set Bt458 read mask register to all planes */ | | 1555 | /* set Bt458 read mask register to all planes */ |
1558 | ngle_bt458_write(memt, memh, 0x08, 0x04); | | 1556 | ngle_bt458_write(memt, memh, 0x08, 0x04); |
1559 | ngle_bt458_write(memt, memh, 0x0a, 0xff); | | 1557 | ngle_bt458_write(memt, memh, 0x0a, 0xff); |
1560 | } | | 1558 | } |
1561 | | | 1559 | |
1562 | void | | 1560 | void |
1563 | ngle_setup_attr_planes(struct sti_screen *scr) | | 1561 | ngle_setup_attr_planes(struct sti_screen *scr) |
1564 | { | | 1562 | { |
1565 | struct sti_rom *rom = scr->scr_rom; | | 1563 | struct sti_rom *rom = scr->scr_rom; |
1566 | bus_space_tag_t memt = rom->memt; | | 1564 | bus_space_tag_t memt = rom->memt; |
1567 | bus_space_handle_t memh = rom->regh[2]; | | 1565 | bus_space_handle_t memh = rom->regh[2]; |
1568 | | | 1566 | |
1569 | ngle_setup_hw(memt, memh); | | 1567 | ngle_setup_hw(memt, memh); |
1570 | bus_space_write_4(memt, memh, NGLE_REG_11, 0x2ea0d000); | | 1568 | bus_space_write_4(memt, memh, NGLE_REG_11, 0x2ea0d000); |
1571 | bus_space_write_4(memt, memh, NGLE_REG_14, 0x23000302); | | 1569 | bus_space_write_4(memt, memh, NGLE_REG_14, 0x23000302); |
1572 | bus_space_write_4(memt, memh, NGLE_REG_12, scr->reg12_value); | | 1570 | bus_space_write_4(memt, memh, NGLE_REG_12, scr->reg12_value); |
1573 | bus_space_write_4(memt, memh, NGLE_REG_8, 0xffffffff); | | 1571 | bus_space_write_4(memt, memh, NGLE_REG_8, 0xffffffff); |
1574 | | | 1572 | |
1575 | bus_space_write_4(memt, memh, NGLE_REG_6, 0x00000000); | | 1573 | bus_space_write_4(memt, memh, NGLE_REG_6, 0x00000000); |
1576 | bus_space_write_4(memt, memh, NGLE_REG_9, | | 1574 | bus_space_write_4(memt, memh, NGLE_REG_9, |
1577 | (scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height); | | 1575 | (scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height); |
1578 | bus_space_write_4(memt, memh, NGLE_REG_6, 0x05000000); | | 1576 | bus_space_write_4(memt, memh, NGLE_REG_6, 0x05000000); |
1579 | bus_space_write_4(memt, memh, NGLE_REG_9, 0x00040001); | | 1577 | bus_space_write_4(memt, memh, NGLE_REG_9, 0x00040001); |
1580 | | | 1578 | |
1581 | ngle_setup_hw(memt, memh); | | 1579 | ngle_setup_hw(memt, memh); |
1582 | bus_space_write_4(memt, memh, NGLE_REG_12, 0x00000000); | | 1580 | bus_space_write_4(memt, memh, NGLE_REG_12, 0x00000000); |
1583 | | | 1581 | |
1584 | ngle_setup_fb(memt, memh, scr->reg10_value); | | 1582 | ngle_setup_fb(memt, memh, scr->reg10_value); |
1585 | } | | 1583 | } |
1586 | | | 1584 | |
1587 | int | | 1585 | int |
1588 | ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count) | | 1586 | ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count) |
1589 | { | | 1587 | { |
1590 | struct sti_rom *rom = scr->scr_rom; | | 1588 | struct sti_rom *rom = scr->scr_rom; |
1591 | bus_space_tag_t memt = rom->memt; | | 1589 | bus_space_tag_t memt = rom->memt; |
1592 | bus_space_handle_t memh = rom->regh[2]; | | 1590 | bus_space_handle_t memh = rom->regh[2]; |
1593 | uint8_t *r, *g, *b; | | 1591 | uint8_t *r, *g, *b; |
1594 | uint32_t cmap_finish; | | 1592 | uint32_t cmap_finish; |
1595 | | | 1593 | |
1596 | if (scr->scr_bpp > 8) | | 1594 | if (scr->scr_bpp > 8) |
1597 | cmap_finish = 0x83000100; | | 1595 | cmap_finish = 0x83000100; |
1598 | else | | 1596 | else |
1599 | cmap_finish = 0x80000100; | | 1597 | cmap_finish = 0x80000100; |
1600 | | | 1598 | |
1601 | r = scr->scr_rcmap + idx; | | 1599 | r = scr->scr_rcmap + idx; |
1602 | g = scr->scr_gcmap + idx; | | 1600 | g = scr->scr_gcmap + idx; |
1603 | b = scr->scr_bcmap + idx; | | 1601 | b = scr->scr_bcmap + idx; |
1604 | | | 1602 | |
1605 | ngle_setup_hw(memt, memh); | | 1603 | ngle_setup_hw(memt, memh); |
1606 | bus_space_write_4(memt, memh, NGLE_REG_10, 0xbbe0f000); | | 1604 | bus_space_write_4(memt, memh, NGLE_REG_10, 0xbbe0f000); |
1607 | bus_space_write_4(memt, memh, NGLE_REG_14, 0x03000300); | | 1605 | bus_space_write_4(memt, memh, NGLE_REG_14, 0x03000300); |
1608 | bus_space_write_4(memt, memh, NGLE_REG_13, 0xffffffff); | | 1606 | bus_space_write_4(memt, memh, NGLE_REG_13, 0xffffffff); |
1609 | | | 1607 | |
1610 | while (count-- != 0) { | | 1608 | while (count-- != 0) { |
1611 | ngle_setup_hw(memt, memh); | | 1609 | ngle_setup_hw(memt, memh); |
1612 | bus_space_write_4(memt, memh, NGLE_REG_3, 0x400 | (idx << 2)); | | 1610 | bus_space_write_4(memt, memh, NGLE_REG_3, 0x400 | (idx << 2)); |
1613 | bus_space_write_4(memt, memh, NGLE_REG_4, | | 1611 | bus_space_write_4(memt, memh, NGLE_REG_4, |
1614 | (*r << 16) | (*g << 8) | *b); | | 1612 | (*r << 16) | (*g << 8) | *b); |
1615 | | | 1613 | |
1616 | idx++; | | 1614 | idx++; |
1617 | r++, g++, b++; | | 1615 | r++, g++, b++; |
1618 | } | | 1616 | } |
1619 | | | 1617 | |
1620 | bus_space_write_4(memt, memh, NGLE_REG_2, 0x400); | | 1618 | bus_space_write_4(memt, memh, NGLE_REG_2, 0x400); |
1621 | bus_space_write_4(memt, memh, scr->cmap_finish_register, cmap_finish); | | 1619 | bus_space_write_4(memt, memh, scr->cmap_finish_register, cmap_finish); |
1622 | ngle_setup_fb(memt, memh, scr->reg10_value); | | 1620 | ngle_setup_fb(memt, memh, scr->reg10_value); |
1623 | | | 1621 | |
1624 | | | 1622 | |
1625 | return 0; | | 1623 | return 0; |
1626 | } | | 1624 | } |
1627 | | | 1625 | |
1628 | void | | 1626 | void |
1629 | ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh) | | 1627 | ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh) |
1630 | { | | 1628 | { |
1631 | uint8_t stat; | | 1629 | uint8_t stat; |
1632 | | | 1630 | |
1633 | do { | | 1631 | do { |
1634 | stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); | | 1632 | stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); |
1635 | if (stat == 0) | | 1633 | if (stat == 0) |
1636 | stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); | | 1634 | stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); |
1637 | } while (stat != 0); | | 1635 | } while (stat != 0); |
1638 | } | | 1636 | } |
1639 | | | 1637 | |
1640 | void | | 1638 | void |
1641 | ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10) | | 1639 | ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10) |
1642 | { | | 1640 | { |
1643 | | | 1641 | |
1644 | ngle_setup_hw(memt, memh); | | 1642 | ngle_setup_hw(memt, memh); |
1645 | bus_space_write_4(memt, memh, NGLE_REG_10, reg10); | | 1643 | bus_space_write_4(memt, memh, NGLE_REG_10, reg10); |
1646 | bus_space_write_4(memt, memh, NGLE_REG_14, 0x83000300); | | 1644 | bus_space_write_4(memt, memh, NGLE_REG_14, 0x83000300); |
1647 | ngle_setup_hw(memt, memh); | | 1645 | ngle_setup_hw(memt, memh); |
1648 | bus_space_write_1(memt, memh, NGLE_REG_16b1, 1); | | 1646 | bus_space_write_1(memt, memh, NGLE_REG_16b1, 1); |
1649 | } | | 1647 | } |
1650 | #endif /* SMALL_KERNEL */ | | 1648 | #endif /* SMALL_KERNEL */ |