xref: /linux/arch/powerpc/platforms/ps3/system-bus.c (revision b454cc6636d254fbf6049b73e9560aee76fb04a3)
1 /*
2  *  PS3 system bus driver.
3  *
4  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
5  *  Copyright 2006 Sony Corp.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; version 2 of the License.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include <linux/kernel.h>
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/dma-mapping.h>
25 #include <linux/err.h>
26 
27 #include <asm/udbg.h>
28 #include <asm/lv1call.h>
29 #include <asm/firmware.h>
30 
31 #include "platform.h"
32 
33 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
34 static void _dump_mmio_region(const struct ps3_mmio_region* r,
35 	const char* func, int line)
36 {
37 	pr_debug("%s:%d: dev       %u:%u\n", func, line, r->did.bus_id,
38 		r->did.dev_id);
39 	pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
40 	pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
41 	pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
42 }
43 
44 int ps3_mmio_region_create(struct ps3_mmio_region *r)
45 {
46 	int result;
47 
48 	result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id,
49 		r->bus_addr, r->len, r->page_size, &r->lpar_addr);
50 
51 	if (result) {
52 		pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
53 			__func__, __LINE__, ps3_result(result));
54 		r->lpar_addr = 0;
55 	}
56 
57 	dump_mmio_region(r);
58 	return result;
59 }
60 
61 int ps3_free_mmio_region(struct ps3_mmio_region *r)
62 {
63 	int result;
64 
65 	result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id,
66 		r->lpar_addr);
67 
68 	if (result)
69 		pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
70 			__func__, __LINE__, ps3_result(result));
71 
72 	r->lpar_addr = 0;
73 	return result;
74 }
75 
76 static int ps3_system_bus_match(struct device *_dev,
77 	struct device_driver *_drv)
78 {
79 	int result;
80 	struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv);
81 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
82 
83 	result = dev->match_id == drv->match_id;
84 
85 	pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__,
86 		dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name,
87 		(result ? "match" : "miss"));
88 	return result;
89 }
90 
91 static int ps3_system_bus_probe(struct device *_dev)
92 {
93 	int result;
94 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
95 	struct ps3_system_bus_driver *drv =
96 		to_ps3_system_bus_driver(_dev->driver);
97 
98 	result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
99 
100 	if (result) {
101 		pr_debug("%s:%d: lv1_open_device failed (%d)\n",
102 			__func__, __LINE__, result);
103 		result = -EACCES;
104 		goto clean_none;
105 	}
106 
107 	if (dev->d_region->did.bus_id) {
108 		result = ps3_dma_region_create(dev->d_region);
109 
110 		if (result) {
111 			pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n",
112 				__func__, __LINE__, result);
113 			BUG_ON("check region type");
114 			result = -EINVAL;
115 			goto clean_device;
116 		}
117 	}
118 
119 	BUG_ON(!drv);
120 
121 	if (drv->probe)
122 		result = drv->probe(dev);
123 	else
124 		pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
125 			dev->core.bus_id);
126 
127 	if (result) {
128 		pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
129 		goto clean_dma;
130 	}
131 
132 	return result;
133 
134 clean_dma:
135 	ps3_dma_region_free(dev->d_region);
136 clean_device:
137 	lv1_close_device(dev->did.bus_id, dev->did.dev_id);
138 clean_none:
139 	return result;
140 }
141 
142 static int ps3_system_bus_remove(struct device *_dev)
143 {
144 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
145 	struct ps3_system_bus_driver *drv =
146 		to_ps3_system_bus_driver(_dev->driver);
147 
148 	if (drv->remove)
149 		drv->remove(dev);
150 	else
151 		pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
152 			dev->core.bus_id);
153 
154 	ps3_dma_region_free(dev->d_region);
155 	ps3_free_mmio_region(dev->m_region);
156 	lv1_close_device(dev->did.bus_id, dev->did.dev_id);
157 
158 	return 0;
159 }
160 
161 struct bus_type ps3_system_bus_type = {
162 	.name = "ps3_system_bus",
163 	.match = ps3_system_bus_match,
164 	.probe = ps3_system_bus_probe,
165 	.remove = ps3_system_bus_remove,
166 };
167 
168 int __init ps3_system_bus_init(void)
169 {
170 	int result;
171 
172 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
173 		return 0;
174 
175 	result = bus_register(&ps3_system_bus_type);
176 	BUG_ON(result);
177 	return result;
178 }
179 
180 core_initcall(ps3_system_bus_init);
181 
182 /* Allocates a contiguous real buffer and creates mappings over it.
183  * Returns the virtual address of the buffer and sets dma_handle
184  * to the dma address (mapping) of the first page.
185  */
186 
187 static void * ps3_alloc_coherent(struct device *_dev, size_t size,
188 	dma_addr_t *dma_handle, gfp_t flag)
189 {
190 	int result;
191 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
192 	unsigned long virt_addr;
193 
194 	BUG_ON(!dev->d_region->bus_addr);
195 
196 	flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
197 	flag |= __GFP_ZERO;
198 
199 	virt_addr = __get_free_pages(flag, get_order(size));
200 
201 	if (!virt_addr) {
202 		pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
203 		goto clean_none;
204 	}
205 
206 	result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle);
207 
208 	if (result) {
209 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
210 			__func__, __LINE__, result);
211 		BUG_ON("check region type");
212 		goto clean_alloc;
213 	}
214 
215 	return (void*)virt_addr;
216 
217 clean_alloc:
218 	free_pages(virt_addr, get_order(size));
219 clean_none:
220 	dma_handle = NULL;
221 	return NULL;
222 }
223 
224 static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
225 	dma_addr_t dma_handle)
226 {
227 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
228 
229 	ps3_dma_unmap(dev->d_region, dma_handle, size);
230 	free_pages((unsigned long)vaddr, get_order(size));
231 }
232 
233 /* Creates TCEs for a user provided buffer.  The user buffer must be
234  * contiguous real kernel storage (not vmalloc).  The address of the buffer
235  * passed here is the kernel (virtual) address of the buffer.  The buffer
236  * need not be page aligned, the dma_addr_t returned will point to the same
237  * byte within the page as vaddr.
238  */
239 
240 static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
241 	enum dma_data_direction direction)
242 {
243 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
244 	int result;
245 	unsigned long bus_addr;
246 
247 	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
248 		&bus_addr);
249 
250 	if (result) {
251 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
252 			__func__, __LINE__, result);
253 	}
254 
255 	return bus_addr;
256 }
257 
258 static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
259 	size_t size, enum dma_data_direction direction)
260 {
261 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
262 	int result;
263 
264 	result = ps3_dma_unmap(dev->d_region, dma_addr, size);
265 
266 	if (result) {
267 		pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
268 			__func__, __LINE__, result);
269 	}
270 }
271 
272 static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
273 	enum dma_data_direction direction)
274 {
275 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
276 	int i;
277 
278 #if defined(CONFIG_PS3_DYNAMIC_DMA)
279 	BUG_ON("do");
280 	return -EPERM;
281 #else
282 	for (i = 0; i < nents; i++, sg++) {
283 		int result = ps3_dma_map(dev->d_region,
284 			page_to_phys(sg->page) + sg->offset, sg->length,
285 			&sg->dma_address);
286 
287 		if (result) {
288 			pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
289 				__func__, __LINE__, result);
290 			return -EINVAL;
291 		}
292 
293 		sg->dma_length = sg->length;
294 	}
295 
296 	return nents;
297 #endif
298 }
299 
300 static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
301 	int nents, enum dma_data_direction direction)
302 {
303 #if defined(CONFIG_PS3_DYNAMIC_DMA)
304 	BUG_ON("do");
305 #endif
306 }
307 
308 static int ps3_dma_supported(struct device *_dev, u64 mask)
309 {
310 	return mask >= DMA_32BIT_MASK;
311 }
312 
313 static struct dma_mapping_ops ps3_dma_ops = {
314 	.alloc_coherent = ps3_alloc_coherent,
315 	.free_coherent = ps3_free_coherent,
316 	.map_single = ps3_map_single,
317 	.unmap_single = ps3_unmap_single,
318 	.map_sg = ps3_map_sg,
319 	.unmap_sg = ps3_unmap_sg,
320 	.dma_supported = ps3_dma_supported
321 };
322 
323 /**
324  * ps3_system_bus_release_device - remove a device from the system bus
325  */
326 
327 static void ps3_system_bus_release_device(struct device *_dev)
328 {
329 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
330 	kfree(dev);
331 }
332 
333 /**
334  * ps3_system_bus_device_register - add a device to the system bus
335  *
336  * ps3_system_bus_device_register() expects the dev object to be allocated
337  * dynamically by the caller.  The system bus takes ownership of the dev
338  * object and frees the object in ps3_system_bus_release_device().
339  */
340 
341 int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
342 {
343 	int result;
344 	static unsigned int dev_count = 1;
345 
346 	dev->core.parent = NULL;
347 	dev->core.bus = &ps3_system_bus_type;
348 	dev->core.release = ps3_system_bus_release_device;
349 
350 	dev->core.archdata.of_node = NULL;
351 	dev->core.archdata.dma_ops = &ps3_dma_ops;
352 	dev->core.archdata.numa_node = 0;
353 
354 	snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
355 		dev_count++);
356 
357 	pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
358 
359 	result = device_register(&dev->core);
360 	return result;
361 }
362 
363 EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
364 
365 int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
366 {
367 	int result;
368 
369 	drv->core.bus = &ps3_system_bus_type;
370 
371 	result = driver_register(&drv->core);
372 	return result;
373 }
374 
375 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
376 
377 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
378 {
379 	driver_unregister(&drv->core);
380 }
381 
382 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
383