xref: /openbmc/linux/arch/mips/sgi-ip22/ip22-gio.c (revision 7b7dfdd2)
1 #include <linux/export.h>
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/slab.h>
5 
6 #include <asm/addrspace.h>
7 #include <asm/paccess.h>
8 #include <asm/gio_device.h>
9 #include <asm/sgi/gio.h>
10 #include <asm/sgi/hpc3.h>
11 #include <asm/sgi/mc.h>
12 #include <asm/sgi/ip22.h>
13 
14 static struct bus_type gio_bus_type;
15 
16 static struct {
17 	const char *name;
18 	__u8	   id;
19 } gio_name_table[] = {
20 	{ .name = "SGI Impact", .id = 0x10 },
21 	{ .name = "Phobos G160", .id = 0x35 },
22 	{ .name = "Phobos G130", .id = 0x36 },
23 	{ .name = "Phobos G100", .id = 0x37 },
24 	{ .name = "Set Engineering GFE", .id = 0x38 },
25 	/* fake IDs */
26 	{ .name = "SGI Newport", .id = 0x7e },
27 	{ .name = "SGI GR2/GR3", .id = 0x7f },
28 };
29 
30 static struct device gio_bus = {
31 	.init_name = "gio",
32 };
33 
34 /**
35  * gio_match_device - Tell if an of_device structure has a matching
36  * gio_match structure
37  * @ids: array of of device match structures to search in
38  * @dev: the of device structure to match against
39  *
40  * Used by a driver to check whether an of_device present in the
41  * system is in its list of supported devices.
42  */
43 const struct gio_device_id *gio_match_device(const struct gio_device_id *match,
44 		     const struct gio_device *dev)
45 {
46 	const struct gio_device_id *ids;
47 
48 	for (ids = match; ids->id != 0xff; ids++)
49 		if (ids->id == dev->id.id)
50 			return ids;
51 
52 	return NULL;
53 }
54 EXPORT_SYMBOL_GPL(gio_match_device);
55 
56 struct gio_device *gio_dev_get(struct gio_device *dev)
57 {
58 	struct device *tmp;
59 
60 	if (!dev)
61 		return NULL;
62 	tmp = get_device(&dev->dev);
63 	if (tmp)
64 		return to_gio_device(tmp);
65 	else
66 		return NULL;
67 }
68 EXPORT_SYMBOL_GPL(gio_dev_get);
69 
70 void gio_dev_put(struct gio_device *dev)
71 {
72 	if (dev)
73 		put_device(&dev->dev);
74 }
75 EXPORT_SYMBOL_GPL(gio_dev_put);
76 
77 /**
78  * gio_release_dev - free an gio device structure when all users of it are finished.
79  * @dev: device that's been disconnected
80  *
81  * Will be called only by the device core when all users of this gio device are
82  * done.
83  */
84 void gio_release_dev(struct device *dev)
85 {
86 	struct gio_device *giodev;
87 
88 	giodev = to_gio_device(dev);
89 	kfree(giodev);
90 }
91 EXPORT_SYMBOL_GPL(gio_release_dev);
92 
93 int gio_device_register(struct gio_device *giodev)
94 {
95 	giodev->dev.bus = &gio_bus_type;
96 	giodev->dev.parent = &gio_bus;
97 	return device_register(&giodev->dev);
98 }
99 EXPORT_SYMBOL_GPL(gio_device_register);
100 
101 void gio_device_unregister(struct gio_device *giodev)
102 {
103 	device_unregister(&giodev->dev);
104 }
105 EXPORT_SYMBOL_GPL(gio_device_unregister);
106 
107 static int gio_bus_match(struct device *dev, struct device_driver *drv)
108 {
109 	struct gio_device *gio_dev = to_gio_device(dev);
110 	struct gio_driver *gio_drv = to_gio_driver(drv);
111 
112 	return gio_match_device(gio_drv->id_table, gio_dev) != NULL;
113 }
114 
115 static int gio_device_probe(struct device *dev)
116 {
117 	int error = -ENODEV;
118 	struct gio_driver *drv;
119 	struct gio_device *gio_dev;
120 	const struct gio_device_id *match;
121 
122 	drv = to_gio_driver(dev->driver);
123 	gio_dev = to_gio_device(dev);
124 
125 	if (!drv->probe)
126 		return error;
127 
128 	gio_dev_get(gio_dev);
129 
130 	match = gio_match_device(drv->id_table, gio_dev);
131 	if (match)
132 		error = drv->probe(gio_dev, match);
133 	if (error)
134 		gio_dev_put(gio_dev);
135 
136 	return error;
137 }
138 
139 static int gio_device_remove(struct device *dev)
140 {
141 	struct gio_device *gio_dev = to_gio_device(dev);
142 	struct gio_driver *drv = to_gio_driver(dev->driver);
143 
144 	if (dev->driver && drv->remove)
145 		drv->remove(gio_dev);
146 	return 0;
147 }
148 
149 static int gio_device_suspend(struct device *dev, pm_message_t state)
150 {
151 	struct gio_device *gio_dev = to_gio_device(dev);
152 	struct gio_driver *drv = to_gio_driver(dev->driver);
153 	int error = 0;
154 
155 	if (dev->driver && drv->suspend)
156 		error = drv->suspend(gio_dev, state);
157 	return error;
158 }
159 
160 static int gio_device_resume(struct device *dev)
161 {
162 	struct gio_device *gio_dev = to_gio_device(dev);
163 	struct gio_driver *drv = to_gio_driver(dev->driver);
164 	int error = 0;
165 
166 	if (dev->driver && drv->resume)
167 		error = drv->resume(gio_dev);
168 	return error;
169 }
170 
171 static void gio_device_shutdown(struct device *dev)
172 {
173 	struct gio_device *gio_dev = to_gio_device(dev);
174 	struct gio_driver *drv = to_gio_driver(dev->driver);
175 
176 	if (dev->driver && drv->shutdown)
177 		drv->shutdown(gio_dev);
178 }
179 
180 static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
181 			     char *buf)
182 {
183 	struct gio_device *gio_dev = to_gio_device(dev);
184 	int len = snprintf(buf, PAGE_SIZE, "gio:%x\n", gio_dev->id.id);
185 
186 	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
187 }
188 
189 static ssize_t name_show(struct device *dev,
190 			 struct device_attribute *attr, char *buf)
191 {
192 	struct gio_device *giodev;
193 
194 	giodev = to_gio_device(dev);
195 	return sprintf(buf, "%s", giodev->name);
196 }
197 
198 static ssize_t id_show(struct device *dev,
199 		       struct device_attribute *attr, char *buf)
200 {
201 	struct gio_device *giodev;
202 
203 	giodev = to_gio_device(dev);
204 	return sprintf(buf, "%x", giodev->id.id);
205 }
206 
207 static struct device_attribute gio_dev_attrs[] = {
208 	__ATTR_RO(modalias),
209 	__ATTR_RO(name),
210 	__ATTR_RO(id),
211 	__ATTR_NULL,
212 };
213 
214 static int gio_device_uevent(struct device *dev, struct kobj_uevent_env *env)
215 {
216 	struct gio_device *gio_dev = to_gio_device(dev);
217 
218 	add_uevent_var(env, "MODALIAS=gio:%x", gio_dev->id.id);
219 	return 0;
220 }
221 
222 int gio_register_driver(struct gio_driver *drv)
223 {
224 	/* initialize common driver fields */
225 	if (!drv->driver.name)
226 		drv->driver.name = drv->name;
227 	if (!drv->driver.owner)
228 		drv->driver.owner = drv->owner;
229 	drv->driver.bus = &gio_bus_type;
230 
231 	/* register with core */
232 	return driver_register(&drv->driver);
233 }
234 EXPORT_SYMBOL_GPL(gio_register_driver);
235 
236 void gio_unregister_driver(struct gio_driver *drv)
237 {
238 	driver_unregister(&drv->driver);
239 }
240 EXPORT_SYMBOL_GPL(gio_unregister_driver);
241 
242 void gio_set_master(struct gio_device *dev)
243 {
244 	u32 tmp = sgimc->giopar;
245 
246 	switch (dev->slotno) {
247 	case 0:
248 		tmp |= SGIMC_GIOPAR_MASTERGFX;
249 		break;
250 	case 1:
251 		tmp |= SGIMC_GIOPAR_MASTEREXP0;
252 		break;
253 	case 2:
254 		tmp |= SGIMC_GIOPAR_MASTEREXP1;
255 		break;
256 	}
257 	sgimc->giopar = tmp;
258 }
259 EXPORT_SYMBOL_GPL(gio_set_master);
260 
261 void ip22_gio_set_64bit(int slotno)
262 {
263 	u32 tmp = sgimc->giopar;
264 
265 	switch (slotno) {
266 	case 0:
267 		tmp |= SGIMC_GIOPAR_GFX64;
268 		break;
269 	case 1:
270 		tmp |= SGIMC_GIOPAR_EXP064;
271 		break;
272 	case 2:
273 		tmp |= SGIMC_GIOPAR_EXP164;
274 		break;
275 	}
276 	sgimc->giopar = tmp;
277 }
278 
279 static int ip22_gio_id(unsigned long addr, u32 *res)
280 {
281 	u8 tmp8;
282 	u8 tmp16;
283 	u32 tmp32;
284 	u8 *ptr8;
285 	u16 *ptr16;
286 	u32 *ptr32;
287 
288 	ptr32 = (void *)CKSEG1ADDR(addr);
289 	if (!get_dbe(tmp32, ptr32)) {
290 		/*
291 		 * We got no DBE, but this doesn't mean anything.
292 		 * If GIO is pipelined (which can't be disabled
293 		 * for GFX slot) we don't get a DBE, but we see
294 		 * the transfer size as data. So we do an 8bit
295 		 * and a 16bit access and check whether the common
296 		 * data matches
297 		 */
298 		ptr8 = (void *)CKSEG1ADDR(addr + 3);
299 		if (get_dbe(tmp8, ptr8)) {
300 			/*
301 			 * 32bit access worked, but 8bit doesn't
302 			 * so we don't see phantom reads on
303 			 * a pipelined bus, but a real card which
304 			 * doesn't support 8 bit reads
305 			 */
306 			*res = tmp32;
307 			return 1;
308 		}
309 		ptr16 = (void *)CKSEG1ADDR(addr + 2);
310 		get_dbe(tmp16, ptr16);
311 		if (tmp8 == (tmp16 & 0xff) &&
312 		    tmp8 == (tmp32 & 0xff) &&
313 		    tmp16 == (tmp32 & 0xffff)) {
314 			*res = tmp32;
315 			return 1;
316 		}
317 	}
318 	return 0; /* nothing here */
319 }
320 
321 #define HQ2_MYSTERY_OFFS       0x6A07C
322 #define NEWPORT_USTATUS_OFFS   0xF133C
323 
324 static int ip22_is_gr2(unsigned long addr)
325 {
326 	u32 tmp;
327 	u32 *ptr;
328 
329 	/* HQ2 only allows 32bit accesses */
330 	ptr = (void *)CKSEG1ADDR(addr + HQ2_MYSTERY_OFFS);
331 	if (!get_dbe(tmp, ptr)) {
332 		if (tmp == 0xdeadbeef)
333 			return 1;
334 	}
335 	return 0;
336 }
337 
338 
339 static void ip22_check_gio(int slotno, unsigned long addr, int irq)
340 {
341 	const char *name = "Unknown";
342 	struct gio_device *gio_dev;
343 	u32 tmp;
344 	__u8 id;
345 	int i;
346 
347 	/* first look for GR2/GR3 by checking mystery register */
348 	if (ip22_is_gr2(addr))
349 		tmp = 0x7f;
350 	else {
351 		if (!ip22_gio_id(addr, &tmp)) {
352 			/*
353 			 * no GIO signature at start address of slot
354 			 * since Newport doesn't have one, we check if
355 			 * user status register is readable
356 			 */
357 			if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp))
358 				tmp = 0x7e;
359 			else
360 				tmp = 0;
361 		}
362 	}
363 	if (tmp) {
364 		id = GIO_ID(tmp);
365 		if (tmp & GIO_32BIT_ID) {
366 			if (tmp & GIO_64BIT_IFACE)
367 				ip22_gio_set_64bit(slotno);
368 		}
369 		for (i = 0; i < ARRAY_SIZE(gio_name_table); i++) {
370 			if (id == gio_name_table[i].id) {
371 				name = gio_name_table[i].name;
372 				break;
373 			}
374 		}
375 		printk(KERN_INFO "GIO: slot %d : %s (id %x)\n",
376 		       slotno, name, id);
377 		gio_dev = kzalloc(sizeof *gio_dev, GFP_KERNEL);
378 		gio_dev->name = name;
379 		gio_dev->slotno = slotno;
380 		gio_dev->id.id = id;
381 		gio_dev->resource.start = addr;
382 		gio_dev->resource.end = addr + 0x3fffff;
383 		gio_dev->resource.flags = IORESOURCE_MEM;
384 		gio_dev->irq = irq;
385 		dev_set_name(&gio_dev->dev, "%d", slotno);
386 		gio_device_register(gio_dev);
387 	} else
388 		printk(KERN_INFO "GIO: slot %d : Empty\n", slotno);
389 }
390 
391 static struct bus_type gio_bus_type = {
392 	.name	   = "gio",
393 	.dev_attrs = gio_dev_attrs,
394 	.match	   = gio_bus_match,
395 	.probe	   = gio_device_probe,
396 	.remove	   = gio_device_remove,
397 	.suspend   = gio_device_suspend,
398 	.resume	   = gio_device_resume,
399 	.shutdown  = gio_device_shutdown,
400 	.uevent	   = gio_device_uevent,
401 };
402 
403 static struct resource gio_bus_resource = {
404 	.start = GIO_SLOT_GFX_BASE,
405 	.end   = GIO_SLOT_GFX_BASE + 0x9fffff,
406 	.name  = "GIO Bus",
407 	.flags = IORESOURCE_MEM,
408 };
409 
410 int __init ip22_gio_init(void)
411 {
412 	unsigned int pbdma __maybe_unused;
413 	int ret;
414 
415 	ret = device_register(&gio_bus);
416 	if (ret)
417 		return ret;
418 
419 	ret = bus_register(&gio_bus_type);
420 	if (!ret) {
421 		request_resource(&iomem_resource, &gio_bus_resource);
422 		printk(KERN_INFO "GIO: Probing bus...\n");
423 
424 		if (ip22_is_fullhouse()) {
425 			/* Indigo2 */
426 			ip22_check_gio(0, GIO_SLOT_GFX_BASE, SGI_GIO_1_IRQ);
427 			ip22_check_gio(1, GIO_SLOT_EXP0_BASE, SGI_GIO_1_IRQ);
428 		} else {
429 			/* Indy/Challenge S */
430 			if (get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1]))
431 				ip22_check_gio(0, GIO_SLOT_GFX_BASE,
432 					       SGI_GIO_0_IRQ);
433 			ip22_check_gio(1, GIO_SLOT_EXP0_BASE, SGI_GIOEXP0_IRQ);
434 			ip22_check_gio(2, GIO_SLOT_EXP1_BASE, SGI_GIOEXP1_IRQ);
435 		}
436 	} else
437 		device_unregister(&gio_bus);
438 
439 	return ret;
440 }
441 
442 subsys_initcall(ip22_gio_init);
443