sti_sgc.c revision 1.10 1 /* $NetBSD: sti_sgc.c,v 1.10 2025/05/28 17:33:38 tsutsui Exp $ */
2 /* $OpenBSD: sti_sgc.c,v 1.14 2007/05/26 00:36:03 krw Exp $ */
3
4 /*
5 * Copyright (c) 2005, Miodrag Vallat
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 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.10 2025/05/28 17:33:38 tsutsui Exp $");
31
32 #include <sys/param.h>
33 #include <sys/device.h>
34 #include <sys/bus.h>
35
36 #include <uvm/uvm_extern.h>
37
38 #include <hp300/dev/sgcvar.h>
39 #include <hp300/dev/sti_sgcvar.h>
40 #include <hp300/dev/sti_machdep.h>
41
42 static int sticonslot = -1;
43
44 static int sti_sgc_match(device_t, struct cfdata *, void *);
45 static void sti_sgc_attach(device_t, device_t, void *);
46
47 static int sti_sgc_probe(bus_space_tag_t, int);
48
49 CFATTACH_DECL_NEW(sti_sgc, sizeof(struct sti_machdep_softc),
50 sti_sgc_match, sti_sgc_attach, NULL, NULL);
51
52 static int
53 sti_sgc_match(device_t parent, struct cfdata *cf, void *aux)
54 {
55 struct sgc_attach_args *saa = aux;
56
57 /*
58 * If we already probed it successfully as a console device, go ahead,
59 * since we will not be able to bus_space_map() again.
60 */
61 if (saa->saa_slot == sticonslot)
62 return 1;
63
64 return sti_sgc_probe(saa->saa_iot, saa->saa_slot);
65 }
66
67 static void
68 sti_sgc_attach(device_t parent, device_t self, void *aux)
69 {
70 struct sti_machdep_softc *sc = device_private(self);
71 struct sti_softc *ssc = &sc->sc_sti;
72 struct sgc_attach_args *saa = aux;
73 bus_space_tag_t bst;
74 bus_space_handle_t romh;
75 bus_addr_t base;
76 u_int romend;
77 int i;
78
79 ssc->sc_dev = self;
80 bst = saa->saa_iot;
81 base = (bus_addr_t)sgc_slottopa(saa->saa_slot);
82 sc->sc_base = base;
83
84 if (saa->saa_slot == sticonslot) {
85 sti_machdep_attach_console(sc);
86 } else {
87 if (bus_space_map(bst, base, PAGE_SIZE, 0, &romh)) {
88 aprint_error(": can't map ROM");
89 return;
90 }
91 /*
92 * Compute real PROM size
93 */
94 romend = sti_rom_size(bst, romh);
95
96 bus_space_unmap(bst, romh, PAGE_SIZE);
97
98 if (bus_space_map(bst, base, romend, 0, &romh)) {
99 aprint_error(": can't map frame buffer");
100 return;
101 }
102
103 ssc->bases[0] = romh;
104 for (i = 0; i < STI_REGION_MAX; i++)
105 ssc->bases[i] = base;
106
107 if (sti_attach_common(ssc, bst, bst, romh,
108 STI_CODEBASE_M68K) != 0)
109 return;
110 }
111
112 sti_machdep_attach(sc);
113 }
114
115 static int
116 sti_sgc_probe(bus_space_tag_t iot, int slot)
117 {
118 bus_space_handle_t ioh;
119 int devtype;
120
121 if (bus_space_map(iot, (bus_addr_t)sgc_slottopa(slot),
122 PAGE_SIZE, 0, &ioh))
123 return 0;
124
125 devtype = bus_space_read_1(iot, ioh, 3);
126
127 bus_space_unmap(iot, ioh, PAGE_SIZE);
128
129 /*
130 * This might not be reliable enough. On the other hand, non-STI
131 * SGC cards will apparently not initialize in the hp300, to the
132 * point of not even answering bus probes (checked with an
133 * Harmony/FDDI SGC card).
134 */
135 if (devtype != STI_DEVTYPE1 && devtype != STI_DEVTYPE4)
136 return 0;
137
138 return 1;
139 }
140
141 int
142 sti_sgc_cnprobe(bus_space_tag_t bst, int slot)
143 {
144 void *va;
145 bus_space_handle_t romh;
146 bus_addr_t base;
147 int devtype, rv = 0;
148
149 base = sgc_slottopa(slot);
150 if (bus_space_map(bst, base, PAGE_SIZE, 0, &romh))
151 return 0;
152
153 va = bus_space_vaddr(bst, romh);
154 if (badaddr(va))
155 goto out;
156
157 devtype = bus_space_read_1(bst, romh, 3);
158 if (devtype == STI_DEVTYPE1 || devtype == STI_DEVTYPE4)
159 rv = 1;
160
161 out:
162 bus_space_unmap(bst, romh, PAGE_SIZE);
163 return rv;
164 }
165
166 void
167 sti_sgc_cnattach(bus_space_tag_t bst, int slot)
168 {
169 paddr_t base;
170
171 base = sgc_slottopa(slot);
172
173 sti_machdep_cnattach(bst, base);
174
175 sticonslot = slot;
176 }
177