xref: /openbsd/sys/arch/hppa/dev/sti_sgc.c (revision 1821443c)
1 /*	$OpenBSD: sti_sgc.c,v 1.16 2003/08/21 18:03:18 mickey Exp $	*/
2 
3 /*
4  * Copyright (c) 2000-2003 Michael Shalayeff
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Michael Shalayeff.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF MIND,
27  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  * These cards has to be known to work so far:
34  *	- HPA1991AGrayscale rev 0.02	(705/35) (byte-wide)
35  *	- HPA1991AC19       rev 0.02	(715/33) (byte-wide)
36  *	- HPA208LC1280      rev 8.04	(712/80) just works
37  */
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/device.h>
42 
43 #include <uvm/uvm.h>
44 
45 #include <machine/bus.h>
46 #include <machine/cpu.h>
47 #include <machine/iomod.h>
48 #include <machine/autoconf.h>
49 
50 #include <dev/wscons/wsdisplayvar.h>
51 #include <dev/wscons/wsconsio.h>
52 
53 #include <dev/ic/stireg.h>
54 #include <dev/ic/stivar.h>
55 
56 #include <hppa/dev/cpudevs.h>
57 
58 #define	STI_MEMSIZE	0x2000000
59 #define	STI_ROMSIZE	0x8000
60 #define	STI_ID_FDDI	0x280b31af	/* Medusa FDDI ROM id */
61 
62 /* gecko optional graphics */
63 #define	STI_GOPT1_REV	0x17
64 #define	STI_GOPT2_REV	0x70
65 
66 /* internal EG */
67 #define	STI_INEG_REV	0x60
68 #define	STI_INEG_PROM	0xf0011000
69 
70 int sti_sgc_probe(struct device *, void *, void *);
71 void sti_sgc_attach(struct device *, struct device *, void *);
72 
73 struct cfattach sti_sgc_ca = {
74 	sizeof(struct sti_softc), sti_sgc_probe, sti_sgc_attach
75 };
76 
77 struct cfattach sti_phantom_ca = {
78 	sizeof(struct sti_softc), sti_sgc_probe, sti_sgc_attach
79 };
80 
81 /*
82  * Locate STI ROM.
83  * On some machines it may not be part of the HPA space.
84  */
85 paddr_t
86 sti_sgc_getrom(int unit, struct confargs *ca)
87 {
88 	paddr_t rom = PAGE0->pd_resv2[1];
89 
90 	if (unit) {
91 		if (ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC &&
92 		    (ca->ca_type.iodc_revision == STI_GOPT1_REV ||
93 		     ca->ca_type.iodc_revision == STI_GOPT2_REV))
94 			/* these two share the onboard's prom */ ;
95 		else
96 			rom = 0;
97 	}
98 
99 	if (rom < HPPA_IOBEGIN) {
100 		if (unit == 0 &&
101 		    ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC &&
102 		    ca->ca_type.iodc_revision == STI_INEG_REV)
103 			rom = STI_INEG_PROM;
104 		else
105 			rom = ca->ca_hpa;
106 	}
107 
108 	return (rom);
109 }
110 
111 int
112 sti_sgc_probe(parent, match, aux)
113 	struct device *parent;
114 	void *match, *aux;
115 {
116 	struct cfdata *cf = match;
117 	struct confargs *ca = aux;
118 	bus_space_handle_t romh;
119 	paddr_t rom;
120 	u_int32_t id;
121 	u_char devtype;
122 	int rv = 0, romunmapped = 0;
123 
124 	if (ca->ca_type.iodc_type != HPPA_TYPE_FIO)
125 		return (0);
126 
127 	/* these can only be graphics anyway */
128 	if (ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC)
129 		return (1);
130 
131 	/* these need futher checking for the graphics id */
132 	if (ca->ca_type.iodc_sv_model != HPPA_FIO_SGC)
133 		return 0;
134 
135 	rom = sti_sgc_getrom(cf->cf_unit, ca);
136 #ifdef STIDEBUG
137 	printf ("sti: hpa=%x, rom=%x\n", ca->ca_hpa, rom);
138 #endif
139 
140 	/* if it does not map, probably part of the lasi space */
141 	if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh))) {
142 #ifdef STIDEBUG
143 		printf ("sti: cannot map rom space (%d)\n", rv);
144 #endif
145 		if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) {
146 			romh = rom;
147 			romunmapped++;
148 		} else {
149 			/* in this case i have no freaking idea */
150 			return 0;
151 		}
152 	}
153 
154 #ifdef STIDEBUG
155 	printf("sti: romh=%x\n", romh);
156 #endif
157 
158 	devtype = bus_space_read_1(ca->ca_iot, romh, 3);
159 
160 #ifdef STIDEBUG
161 	printf("sti: devtype=%d\n", devtype);
162 #endif
163 	rv = 1;
164 	switch (devtype) {
165 	case STI_DEVTYPE4:
166 		id = bus_space_read_4(ca->ca_iot, romh, 0x8);
167 		break;
168 	case STI_DEVTYPE1:
169 		id = (bus_space_read_1(ca->ca_iot, romh, 0x10 +  3) << 24) |
170 		     (bus_space_read_1(ca->ca_iot, romh, 0x10 +  7) << 16) |
171 		     (bus_space_read_1(ca->ca_iot, romh, 0x10 + 11) <<  8) |
172 		     (bus_space_read_1(ca->ca_iot, romh, 0x10 + 15));
173 
174 		break;
175 	default:
176 #ifdef STIDEBUG
177 		printf("sti: unknown type (%x)\n", devtype);
178 #endif
179 		rv = 0;
180 	}
181 
182 	if (rv &&
183 	    ca->ca_type.iodc_sv_model == HPPA_FIO_SGC && id == STI_ID_FDDI) {
184 #ifdef STIDEBUG
185 		printf("sti: not a graphics device\n");
186 #endif
187 		rv = 0;
188 	}
189 
190 	if (!romunmapped)
191 		bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE);
192 	return (rv);
193 }
194 
195 void
196 sti_sgc_attach(parent, self, aux)
197 	struct device *parent, *self;
198 	void *aux;
199 {
200 	struct sti_softc *sc = (void *)self;
201 	struct confargs *ca = aux;
202 	paddr_t rom;
203 	int rv;
204 
205 	rom = sti_sgc_getrom(sc->sc_dev.dv_cfdata->cf_unit, ca);
206 
207 #ifdef STIDEBUG
208 	printf("sti: hpa=%x, rom=%x\n", ca->ca_hpa, rom);
209 #endif
210 	sc->memt = sc->iot = ca->ca_iot;
211 
212 	if ((rv = bus_space_map(ca->ca_iot, ca->ca_hpa, STI_MEMSIZE, 0,
213 	    &sc->ioh))) {
214 #ifdef STIDEBUG
215 		printf(": cannot map io space (%d)\n", rv);
216 #endif
217 		return;
218 	}
219 
220 	/* if it does not map, probably part of the lasi space */
221 	if (rom == ca->ca_hpa)
222 		sc->romh = sc->ioh;
223 	else if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &sc->romh))) {
224 		if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN)
225 			sc->romh = rom;
226 		else {
227 #ifdef STIDEBUG
228 			printf (": cannot map rom space (%d)\n", rv);
229 #endif
230 			/* in this case i have no freaking idea */
231 			bus_space_unmap(ca->ca_iot, sc->ioh,  STI_MEMSIZE);
232 			return;
233 		}
234 	}
235 
236 #ifdef STIDEBUG
237 	printf("sti: ioh=%x, romh=%x\n", sc->ioh, sc->romh);
238 #endif
239 	sc->sc_devtype = bus_space_read_1(sc->iot, sc->romh, 3);
240 	if (ca->ca_hpa == (hppa_hpa_t)PAGE0->mem_cons.pz_hpa)
241 		sc->sc_flags |= STI_CONSOLE;
242 	sti_attach_common(sc);
243 }
244