grf_nubus.c revision 1.14 1 /* $NetBSD: grf_nubus.c,v 1.14 1996/10/13 03:21:19 christos Exp $ */
2
3 /*
4 * Copyright (c) 1995 Allen Briggs. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Allen Briggs.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 /*
32 * Device-specific routines for handling Nubus-based video cards.
33 */
34
35 #include <sys/param.h>
36
37 #include <sys/device.h>
38 #include <sys/ioctl.h>
39 #include <sys/file.h>
40 #include <sys/malloc.h>
41 #include <sys/mman.h>
42 #include <sys/proc.h>
43 #include <sys/systm.h>
44
45 #include <machine/cpu.h>
46 #include <machine/grfioctl.h>
47 #include <machine/viareg.h>
48
49 #include "nubus.h"
50 #include "grfvar.h"
51
52 static void load_image_data __P((caddr_t data, struct image_data *image));
53 static void grfmv_intr __P((void *vsc, int slot));
54 static int get_vrsrcid __P((nubus_slot *slot));
55
56 static char zero = 0;
57
58 static int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg));
59 static caddr_t grfmv_phys __P((struct grf_softc *gp, vm_offset_t addr));
60 static int grfmv_match __P((struct device *, void *, void *));
61 static void grfmv_attach __P((struct device *, struct device *, void *));
62
63 struct cfdriver macvid_cd = {
64 NULL, "macvid", DV_DULL
65 };
66
67 struct cfattach macvid_ca = {
68 sizeof(struct grfbus_softc), grfmv_match, grfmv_attach
69 };
70
71 static void
72 load_image_data(data, image)
73 caddr_t data;
74 struct image_data *image;
75 {
76 bcopy(data , &image->size, 4);
77 bcopy(data + 4, &image->offset, 4);
78 bcopy(data + 8, &image->rowbytes, 2);
79 bcopy(data + 10, &image->top, 2);
80 bcopy(data + 12, &image->left, 2);
81 bcopy(data + 14, &image->bottom, 2);
82 bcopy(data + 16, &image->right, 2);
83 bcopy(data + 18, &image->version, 2);
84 bcopy(data + 20, &image->packType, 2);
85 bcopy(data + 22, &image->packSize, 4);
86 bcopy(data + 26, &image->hRes, 4);
87 bcopy(data + 30, &image->vRes, 4);
88 bcopy(data + 34, &image->pixelType, 2);
89 bcopy(data + 36, &image->pixelSize, 2);
90 bcopy(data + 38, &image->cmpCount, 2);
91 bcopy(data + 40, &image->cmpSize, 2);
92 bcopy(data + 42, &image->planeBytes, 4);
93 }
94
95 /*ARGSUSED*/
96 static void
97 grfmv_intr(vsc, slot)
98 void *vsc;
99 int slot;
100 {
101 caddr_t slotbase;
102 struct grfbus_softc *sc;
103
104 sc = (struct grfbus_softc *) vsc;
105 slotbase = (caddr_t) sc->sc_slot.virtual_base;
106 slotbase[0xa0000] = zero;
107 }
108
109 static int
110 get_vrsrcid(slot)
111 nubus_slot *slot;
112 {
113 extern u_short mac68k_vrsrc_vec[];
114 int i;
115
116 for (i = 0 ; i < 6 ; i++)
117 if ((mac68k_vrsrc_vec[i] & 0xff) == slot->slot)
118 return ((mac68k_vrsrc_vec[i] >> 8) & 0xff);
119 return 0x80;
120 }
121
122 static int
123 grfmv_match(parent, self, aux)
124 struct device *parent;
125 void *self, *aux;
126 {
127 struct grfbus_softc *sc;
128 nubus_slot *slot = (nubus_slot *) aux;
129 nubus_dir dir, *dirp, *dirp2;
130 nubus_dirent dirent, *direntp;
131 nubus_type slottype;
132 int vrsrc;
133
134 sc = (struct grfbus_softc *) self; /* XXX: indirect brokenness */
135 dirp = &dir;
136 direntp = &dirent;
137 nubus_get_main_dir(slot, dirp);
138
139 vrsrc = get_vrsrcid(slot);
140 if (nubus_find_rsrc(slot, dirp, vrsrc, direntp) <= 0) {
141 if ( (vrsrc != 128)
142 || (nubus_find_rsrc(slot, dirp, 129, direntp) <= 0)) {
143 return 0;
144 }
145 }
146
147 dirp2 = (nubus_dir *) &sc->board_dir;
148 nubus_get_dir_from_rsrc(slot, direntp, dirp2);
149
150 if (nubus_find_rsrc(slot, dirp2, NUBUS_RSRC_TYPE, direntp) <= 0)
151 /* Type is a required entry... This should never happen. */
152 return 0;
153
154 if (nubus_get_ind_data(slot, direntp,
155 (caddr_t) &slottype, sizeof(nubus_type)) <= 0)
156 return 0;
157
158 if (slottype.category != NUBUS_CATEGORY_DISPLAY)
159 return 0;
160
161 if (slottype.type != NUBUS_TYPE_VIDEO)
162 return 0;
163
164 if (slottype.drsw != NUBUS_DRSW_APPLE)
165 return 0;
166
167 /*
168 * If we've gotten this far, then we're dealing with a real-live
169 * Apple QuickDraw-compatible display card resource. Now, how to
170 * determine that this is an active resource??? Dunno. But we'll
171 * proceed like it is.
172 */
173
174 sc->card_id = slottype.drhw;
175
176 sc->sc_slot = *slot;
177
178 /* Need to load display info (and driver?), etc... */
179
180 return 1;
181 }
182
183 static void
184 grfmv_attach(parent, self, aux)
185 struct device *parent, *self;
186 void *aux;
187 {
188 struct grfbus_softc *sc;
189 struct image_data image_store, image;
190 struct grfmode *gm;
191 char cardname[CARD_NAME_LEN];
192 nubus_dirent dirent;
193 nubus_dir mode_dir;
194 int mode;
195
196 sc = (struct grfbus_softc *) self;
197 gm = &sc->curr_mode;
198
199 mode = NUBUS_RSRC_FIRSTMODE;
200 if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) {
201 printf("\n%s: probe failed to get board rsrc.\n",
202 sc->sc_dev.dv_xname);
203 return;
204 }
205
206 nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &mode_dir);
207
208 if (nubus_find_rsrc(&sc->sc_slot, &mode_dir, VID_PARAMS, &dirent)
209 <= 0) {
210 printf("\n%s: probe failed to get mode dir.\n",
211 sc->sc_dev.dv_xname);
212 return;
213 }
214
215 if (nubus_get_ind_data(&sc->sc_slot, &dirent, (caddr_t) &image_store,
216 sizeof(struct image_data)) <= 0) {
217 printf("\n%s: probe failed to get indirect mode data.\n",
218 sc->sc_dev.dv_xname);
219 return;
220 }
221
222 load_image_data((caddr_t) &image_store, &image);
223
224 gm->mode_id = mode;
225 gm->fbbase = (caddr_t) (sc->sc_slot.virtual_base + image.offset);
226 gm->fboff = image.offset;
227 gm->rowbytes = image.rowbytes;
228 gm->width = image.right - image.left;
229 gm->height = image.bottom - image.top;
230 gm->fbsize = sc->curr_mode.height * sc->curr_mode.rowbytes;
231 gm->hres = image.hRes;
232 gm->vres = image.vRes;
233 gm->ptype = image.pixelType;
234 gm->psize = image.pixelSize;
235
236 strncpy(cardname, nubus_get_card_name(&sc->sc_slot),
237 CARD_NAME_LEN);
238 cardname[CARD_NAME_LEN-1] = '\0';
239
240 printf(": %s\n", cardname);
241
242 add_nubus_intr(sc->sc_slot.slot, grfmv_intr, sc);
243
244 /* Perform common video attachment. */
245 grf_establish(sc, &sc->sc_slot, grfmv_mode, grfmv_phys);
246 }
247
248 static int
249 grfmv_mode(gp, cmd, arg)
250 struct grf_softc *gp;
251 int cmd;
252 void *arg;
253 {
254 switch (cmd) {
255 case GM_GRFON:
256 case GM_GRFOFF:
257 return 0;
258 case GM_CURRMODE:
259 break;
260 case GM_NEWMODE:
261 break;
262 case GM_LISTMODES:
263 break;
264 }
265 return EINVAL;
266 }
267
268 static caddr_t
269 grfmv_phys(gp, addr)
270 struct grf_softc *gp;
271 vm_offset_t addr;
272 {
273 return (caddr_t) (NUBUS_SLOT_TO_PADDR(gp->sc_slot->slot) +
274 (addr - gp->sc_slot->virtual_base));
275 }
276