diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 00:54:17 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-27 22:40:34 -0400 |
commit | 7974dd1bdb43aaf5b45a915c6b439d11733450fc (patch) | |
tree | 716712130efe76478612a719fba409554cbff59b /drivers/gpu/drm/nouveau | |
parent | 168c2e213d3a9b605856d3676d9e93733c8b37d3 (diff) |
drm/nouveau/device: separate construction of pci/tegra devices
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/os.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/pci.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 104 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | 100 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 66 |
11 files changed, 307 insertions, 54 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h index bdd05ee7ec72..54492cb5011b 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/os.h +++ b/drivers/gpu/drm/nouveau/include/nvif/os.h | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
29 | 29 | ||
30 | #include <soc/tegra/fuse.h> | ||
31 | |||
30 | #ifndef ioread32_native | 32 | #ifndef ioread32_native |
31 | #ifdef __BIG_ENDIAN | 33 | #ifdef __BIG_ENDIAN |
32 | #define ioread16_native ioread16be | 34 | #define ioread16_native ioread16be |
@@ -40,5 +42,4 @@ | |||
40 | #define iowrite32_native iowrite32 | 42 | #define iowrite32_native iowrite32 |
41 | #endif /* def __BIG_ENDIAN else */ | 43 | #endif /* def __BIG_ENDIAN else */ |
42 | #endif /* !ioread32_native */ | 44 | #endif /* !ioread32_native */ |
43 | |||
44 | #endif | 45 | #endif |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h index 977c8a85e119..dd0db88f8213 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h | |||
@@ -28,7 +28,9 @@ nvkm_client(void *obj) | |||
28 | struct nvkm_object *client = nv_object(obj); | 28 | struct nvkm_object *client = nv_object(obj); |
29 | while (client && client->parent) | 29 | while (client && client->parent) |
30 | client = client->parent; | 30 | client = client->parent; |
31 | return (void *)client; | 31 | if (client && nv_iclass(client, NV_CLIENT_CLASS)) |
32 | return (void *)client; | ||
33 | return NULL; | ||
32 | } | 34 | } |
33 | 35 | ||
34 | int nvkm_client_new(const char *name, u64 device, const char *cfg, | 36 | int nvkm_client_new(const char *name, u64 device, const char *cfg, |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 875c247d4cfc..eb843e3ff005 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h | |||
@@ -65,22 +65,25 @@ enum nvkm_devidx { | |||
65 | struct nvkm_device { | 65 | struct nvkm_device { |
66 | struct nvkm_engine engine; | 66 | struct nvkm_engine engine; |
67 | 67 | ||
68 | const struct nvkm_device_func *func; | ||
69 | const struct nvkm_device_quirk *quirk; | ||
70 | struct device *dev; | ||
71 | u64 handle; | ||
72 | const char *name; | ||
73 | const char *cfgopt; | ||
74 | const char *dbgopt; | ||
75 | |||
68 | struct list_head head; | 76 | struct list_head head; |
69 | struct mutex mutex; | 77 | struct mutex mutex; |
70 | int refcount; | 78 | int refcount; |
71 | 79 | ||
72 | struct pci_dev *pdev; | 80 | struct pci_dev *pdev; |
73 | struct platform_device *platformdev; | 81 | struct platform_device *platformdev; |
74 | struct device *dev; | ||
75 | u64 handle; | ||
76 | 82 | ||
77 | void __iomem *pri; | 83 | void __iomem *pri; |
78 | 84 | ||
79 | struct nvkm_event event; | 85 | struct nvkm_event event; |
80 | 86 | ||
81 | const char *cfgopt; | ||
82 | const char *dbgopt; | ||
83 | const char *name; | ||
84 | const char *cname; | 87 | const char *cname; |
85 | u64 disable_mask; | 88 | u64 disable_mask; |
86 | 89 | ||
@@ -150,6 +153,17 @@ struct nvkm_device { | |||
150 | struct nouveau_platform_gpu *gpu; | 153 | struct nouveau_platform_gpu *gpu; |
151 | }; | 154 | }; |
152 | 155 | ||
156 | struct nvkm_device_func { | ||
157 | struct nvkm_device_pci *(*pci)(struct nvkm_device *); | ||
158 | struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); | ||
159 | void *(*dtor)(struct nvkm_device *); | ||
160 | int (*preinit)(struct nvkm_device *); | ||
161 | void (*fini)(struct nvkm_device *, bool suspend); | ||
162 | }; | ||
163 | |||
164 | struct nvkm_device_quirk { | ||
165 | }; | ||
166 | |||
153 | struct nvkm_device *nvkm_device_find(u64 name); | 167 | struct nvkm_device *nvkm_device_find(u64 name); |
154 | int nvkm_device_list(u64 *name, int size); | 168 | int nvkm_device_list(u64 *name, int size); |
155 | 169 | ||
@@ -214,13 +228,7 @@ enum nv_bus_type { | |||
214 | 228 | ||
215 | extern struct nvkm_ofuncs nvkm_udevice_ofuncs; | 229 | extern struct nvkm_ofuncs nvkm_udevice_ofuncs; |
216 | 230 | ||
217 | int nvkm_device_new(void *, enum nv_bus_type type, u64 name, | ||
218 | const char *sname, const char *cfg, const char *dbg, | ||
219 | bool detect, bool mmio, u64 subdev_mask, | ||
220 | struct nvkm_device **); | ||
221 | void nvkm_device_del(struct nvkm_device **); | 231 | void nvkm_device_del(struct nvkm_device **); |
222 | int nvkm_device_init(struct nvkm_device *); | ||
223 | int nvkm_device_fini(struct nvkm_device *, bool suspend); | ||
224 | 232 | ||
225 | /* device logging */ | 233 | /* device logging */ |
226 | #define nvdev_printk_(d,l,p,f,a...) do { \ | 234 | #define nvdev_printk_(d,l,p,f,a...) do { \ |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h new file mode 100644 index 000000000000..78d41be20b8c --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __NVKM_DEVICE_PCI_H__ | ||
2 | #define __NVKM_DEVICE_PCI_H__ | ||
3 | #include <core/device.h> | ||
4 | |||
5 | struct nvkm_device_pci { | ||
6 | struct nvkm_device device; | ||
7 | struct pci_dev *pdev; | ||
8 | bool suspend; | ||
9 | }; | ||
10 | |||
11 | int nvkm_device_pci_new(struct pci_dev *, const char *cfg, const char *dbg, | ||
12 | bool detect, bool mmio, u64 subdev_mask, | ||
13 | struct nvkm_device **); | ||
14 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h new file mode 100644 index 000000000000..162986e7f8c4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __NVKM_DEVICE_TEGRA_H__ | ||
2 | #define __NVKM_DEVICE_TEGRA_H__ | ||
3 | #include <core/device.h> | ||
4 | |||
5 | struct nvkm_device_tegra { | ||
6 | struct nvkm_device device; | ||
7 | struct platform_device *pdev; | ||
8 | }; | ||
9 | |||
10 | int nvkm_device_tegra_new(struct platform_device *, | ||
11 | const char *cfg, const char *dbg, | ||
12 | bool detect, bool mmio, u64 subdev_mask, | ||
13 | struct nvkm_device **); | ||
14 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 37dbd5e1c08f..e638ae7c00c2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -32,9 +32,10 @@ | |||
32 | #include "drmP.h" | 32 | #include "drmP.h" |
33 | #include "drm_crtc_helper.h" | 33 | #include "drm_crtc_helper.h" |
34 | 34 | ||
35 | #include <core/device.h> | ||
36 | #include <core/gpuobj.h> | 35 | #include <core/gpuobj.h> |
37 | #include <core/option.h> | 36 | #include <core/option.h> |
37 | #include <core/pci.h> | ||
38 | #include <core/tegra.h> | ||
38 | 39 | ||
39 | #include "nouveau_drm.h" | 40 | #include "nouveau_drm.h" |
40 | #include "nouveau_dma.h" | 41 | #include "nouveau_dma.h" |
@@ -326,9 +327,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev, | |||
326 | remove_conflicting_framebuffers(aper, "nouveaufb", boot); | 327 | remove_conflicting_framebuffers(aper, "nouveaufb", boot); |
327 | kfree(aper); | 328 | kfree(aper); |
328 | 329 | ||
329 | ret = nvkm_device_new(pdev, NVKM_BUS_PCI, nouveau_pci_name(pdev), | 330 | ret = nvkm_device_pci_new(pdev, nouveau_config, nouveau_debug, |
330 | pci_name(pdev), nouveau_config, nouveau_debug, | 331 | true, true, ~0ULL, &device); |
331 | true, true, ~0ULL, &device); | ||
332 | if (ret) | 332 | if (ret) |
333 | return ret; | 333 | return ret; |
334 | 334 | ||
@@ -1036,11 +1036,8 @@ nouveau_platform_device_create(struct platform_device *pdev, | |||
1036 | struct drm_device *drm; | 1036 | struct drm_device *drm; |
1037 | int err; | 1037 | int err; |
1038 | 1038 | ||
1039 | err = nvkm_device_new(pdev, NVKM_BUS_PLATFORM, | 1039 | err = nvkm_device_tegra_new(pdev, nouveau_config, nouveau_debug, |
1040 | nouveau_platform_name(pdev), | 1040 | true, true, ~0ULL, pdevice); |
1041 | dev_name(&pdev->dev), nouveau_config, | ||
1042 | nouveau_debug, true, true, ~0ULL, | ||
1043 | pdevice); | ||
1044 | if (err) | 1041 | if (err) |
1045 | goto err_free; | 1042 | goto err_free; |
1046 | 1043 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild index 47c8fe8f9e3e..91110cd2562e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild | |||
@@ -1,6 +1,8 @@ | |||
1 | nvkm-y += nvkm/engine/device/acpi.o | 1 | nvkm-y += nvkm/engine/device/acpi.o |
2 | nvkm-y += nvkm/engine/device/base.o | 2 | nvkm-y += nvkm/engine/device/base.o |
3 | nvkm-y += nvkm/engine/device/ctrl.o | 3 | nvkm-y += nvkm/engine/device/ctrl.o |
4 | nvkm-y += nvkm/engine/device/pci.o | ||
5 | nvkm-y += nvkm/engine/device/tegra.o | ||
4 | nvkm-y += nvkm/engine/device/user.o | 6 | nvkm-y += nvkm/engine/device/user.o |
5 | 7 | ||
6 | nvkm-y += nvkm/engine/device/nv04.o | 8 | nvkm-y += nvkm/engine/device/nv04.o |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index b7892e6f080b..c7d8e2902c6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |||
@@ -32,19 +32,25 @@ | |||
32 | static DEFINE_MUTEX(nv_devices_mutex); | 32 | static DEFINE_MUTEX(nv_devices_mutex); |
33 | static LIST_HEAD(nv_devices); | 33 | static LIST_HEAD(nv_devices); |
34 | 34 | ||
35 | struct nvkm_device * | 35 | static struct nvkm_device * |
36 | nvkm_device_find(u64 name) | 36 | nvkm_device_find_locked(u64 handle) |
37 | { | 37 | { |
38 | struct nvkm_device *device, *match = NULL; | 38 | struct nvkm_device *device; |
39 | mutex_lock(&nv_devices_mutex); | ||
40 | list_for_each_entry(device, &nv_devices, head) { | 39 | list_for_each_entry(device, &nv_devices, head) { |
41 | if (device->handle == name) { | 40 | if (device->handle == handle) |
42 | match = device; | 41 | return device; |
43 | break; | ||
44 | } | ||
45 | } | 42 | } |
43 | return NULL; | ||
44 | } | ||
45 | |||
46 | struct nvkm_device * | ||
47 | nvkm_device_find(u64 handle) | ||
48 | { | ||
49 | struct nvkm_device *device; | ||
50 | mutex_lock(&nv_devices_mutex); | ||
51 | device = nvkm_device_find_locked(handle); | ||
46 | mutex_unlock(&nv_devices_mutex); | 52 | mutex_unlock(&nv_devices_mutex); |
47 | return match; | 53 | return device; |
48 | } | 54 | } |
49 | 55 | ||
50 | int | 56 | int |
@@ -62,6 +68,7 @@ nvkm_device_list(u64 *name, int size) | |||
62 | } | 68 | } |
63 | 69 | ||
64 | #include <core/parent.h> | 70 | #include <core/parent.h> |
71 | #include <core/client.h> | ||
65 | 72 | ||
66 | struct nvkm_device * | 73 | struct nvkm_device * |
67 | nv_device(void *obj) | 74 | nv_device(void *obj) |
@@ -70,7 +77,8 @@ nv_device(void *obj) | |||
70 | 77 | ||
71 | if (device->engine == NULL) { | 78 | if (device->engine == NULL) { |
72 | while (device && device->parent) { | 79 | while (device && device->parent) { |
73 | if (nv_mclass(device) == 0x0080) { | 80 | if (!nv_iclass(device, NV_SUBDEV_CLASS) && |
81 | device->parent == &nvkm_client(device)->namedb.parent.object) { | ||
74 | struct { | 82 | struct { |
75 | struct nvkm_parent base; | 83 | struct nvkm_parent base; |
76 | struct nvkm_device *device; | 84 | struct nvkm_device *device; |
@@ -125,6 +133,9 @@ nvkm_device_fini(struct nvkm_device *device, bool suspend) | |||
125 | } | 133 | } |
126 | 134 | ||
127 | ret = nvkm_acpi_fini(device, suspend); | 135 | ret = nvkm_acpi_fini(device, suspend); |
136 | |||
137 | if (device->func->fini) | ||
138 | device->func->fini(device, suspend); | ||
128 | fail: | 139 | fail: |
129 | for (; ret && i < NVDEV_SUBDEV_NR; i++) { | 140 | for (; ret && i < NVDEV_SUBDEV_NR; i++) { |
130 | if ((subdev = device->subdev[i])) { | 141 | if ((subdev = device->subdev[i])) { |
@@ -141,11 +152,39 @@ fail: | |||
141 | } | 152 | } |
142 | 153 | ||
143 | int | 154 | int |
155 | nvkm_device_preinit(struct nvkm_device *device) | ||
156 | { | ||
157 | int ret; | ||
158 | s64 time; | ||
159 | |||
160 | nvdev_trace(device, "preinit running...\n"); | ||
161 | time = ktime_to_us(ktime_get()); | ||
162 | |||
163 | if (device->func->preinit) { | ||
164 | ret = device->func->preinit(device); | ||
165 | if (ret) | ||
166 | goto fail; | ||
167 | } | ||
168 | |||
169 | time = ktime_to_us(ktime_get()) - time; | ||
170 | nvdev_trace(device, "preinit completed in %lldus\n", time); | ||
171 | return 0; | ||
172 | |||
173 | fail: | ||
174 | nvdev_error(device, "preinit failed with %d\n", ret); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | int | ||
144 | nvkm_device_init(struct nvkm_device *device) | 179 | nvkm_device_init(struct nvkm_device *device) |
145 | { | 180 | { |
146 | struct nvkm_object *subdev; | 181 | struct nvkm_object *subdev; |
147 | int ret, i = 0, c; | 182 | int ret, i = 0, c; |
148 | 183 | ||
184 | ret = nvkm_device_preinit(device); | ||
185 | if (ret) | ||
186 | return ret; | ||
187 | |||
149 | ret = nvkm_acpi_init(device); | 188 | ret = nvkm_acpi_init(device); |
150 | if (ret) | 189 | if (ret) |
151 | goto fail; | 190 | goto fail; |
@@ -287,12 +326,6 @@ nv_device_get_irq(struct nvkm_device *device, bool stall) | |||
287 | } | 326 | } |
288 | } | 327 | } |
289 | 328 | ||
290 | static struct nvkm_oclass | ||
291 | nvkm_device_oclass = { | ||
292 | .ofuncs = &(struct nvkm_ofuncs) { | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | void | 329 | void |
297 | nvkm_device_del(struct nvkm_device **pdevice) | 330 | nvkm_device_del(struct nvkm_device **pdevice) |
298 | { | 331 | { |
@@ -308,20 +341,28 @@ nvkm_device_del(struct nvkm_device **pdevice) | |||
308 | if (device->pri) | 341 | if (device->pri) |
309 | iounmap(device->pri); | 342 | iounmap(device->pri); |
310 | list_del(&device->head); | 343 | list_del(&device->head); |
344 | |||
345 | if (device->func->dtor) | ||
346 | *pdevice = device->func->dtor(device); | ||
311 | mutex_unlock(&nv_devices_mutex); | 347 | mutex_unlock(&nv_devices_mutex); |
312 | 348 | ||
313 | nvkm_engine_destroy(&device->engine); | 349 | kfree(*pdevice); |
314 | *pdevice = NULL; | 350 | *pdevice = NULL; |
315 | } | 351 | } |
316 | } | 352 | } |
317 | 353 | ||
354 | static const struct nvkm_engine_func | ||
355 | nvkm_device_func = { | ||
356 | }; | ||
357 | |||
318 | int | 358 | int |
319 | nvkm_device_new(void *dev, enum nv_bus_type type, u64 name, | 359 | nvkm_device_ctor(const struct nvkm_device_func *func, |
320 | const char *sname, const char *cfg, const char *dbg, | 360 | const struct nvkm_device_quirk *quirk, |
321 | bool detect, bool mmio, u64 subdev_mask, | 361 | void *dev, enum nv_bus_type type, u64 handle, |
322 | struct nvkm_device **pdevice) | 362 | const char *name, const char *cfg, const char *dbg, |
363 | bool detect, bool mmio, u64 subdev_mask, | ||
364 | struct nvkm_device *device) | ||
323 | { | 365 | { |
324 | struct nvkm_device *device; | ||
325 | u64 mmio_base, mmio_size; | 366 | u64 mmio_base, mmio_size; |
326 | u32 boot0, strap; | 367 | u32 boot0, strap; |
327 | void __iomem *map; | 368 | void __iomem *map; |
@@ -329,17 +370,17 @@ nvkm_device_new(void *dev, enum nv_bus_type type, u64 name, | |||
329 | int i; | 370 | int i; |
330 | 371 | ||
331 | mutex_lock(&nv_devices_mutex); | 372 | mutex_lock(&nv_devices_mutex); |
332 | list_for_each_entry(device, &nv_devices, head) { | 373 | if (nvkm_device_find_locked(handle)) |
333 | if (device->handle == name) | 374 | goto done; |
334 | goto done; | ||
335 | } | ||
336 | 375 | ||
337 | ret = nvkm_engine_create(NULL, NULL, &nvkm_device_oclass, true, | 376 | ret = nvkm_engine_ctor(&nvkm_device_func, device, 0, 0, |
338 | "DEVICE", "device", &device); | 377 | true, &device->engine); |
339 | *pdevice = device; | 378 | device->engine.subdev.object.parent = NULL; |
379 | device->func = func; | ||
340 | if (ret) | 380 | if (ret) |
341 | goto done; | 381 | goto done; |
342 | 382 | ||
383 | device->quirk = quirk; | ||
343 | switch (type) { | 384 | switch (type) { |
344 | case NVKM_BUS_PCI: | 385 | case NVKM_BUS_PCI: |
345 | device->pdev = dev; | 386 | device->pdev = dev; |
@@ -350,12 +391,11 @@ nvkm_device_new(void *dev, enum nv_bus_type type, u64 name, | |||
350 | device->dev = &device->platformdev->dev; | 391 | device->dev = &device->platformdev->dev; |
351 | break; | 392 | break; |
352 | } | 393 | } |
353 | device->handle = name; | 394 | device->handle = handle; |
354 | device->cfgopt = cfg; | 395 | device->cfgopt = cfg; |
355 | device->dbgopt = dbg; | 396 | device->dbgopt = dbg; |
356 | device->name = sname; | 397 | device->name = name; |
357 | 398 | ||
358 | nv_subdev(device)->debug = nvkm_dbgopt(device->dbgopt, "DEVICE"); | ||
359 | list_add_tail(&device->head, &nv_devices); | 399 | list_add_tail(&device->head, &nv_devices); |
360 | 400 | ||
361 | ret = nvkm_event_init(&nvkm_device_event_func, 1, 1, &device->event); | 401 | ret = nvkm_event_init(&nvkm_device_event_func, 1, 1, &device->event); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c new file mode 100644 index 000000000000..1a1d1e584a7f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs <bskeggs@redhat.com> | ||
23 | */ | ||
24 | #include <core/pci.h> | ||
25 | #include "priv.h" | ||
26 | |||
27 | static struct nvkm_device_pci * | ||
28 | nvkm_device_pci(struct nvkm_device *device) | ||
29 | { | ||
30 | return container_of(device, struct nvkm_device_pci, device); | ||
31 | } | ||
32 | |||
33 | static void | ||
34 | nvkm_device_pci_fini(struct nvkm_device *device, bool suspend) | ||
35 | { | ||
36 | struct nvkm_device_pci *pdev = nvkm_device_pci(device); | ||
37 | if (suspend) { | ||
38 | pci_disable_device(pdev->pdev); | ||
39 | pdev->suspend = true; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | static int | ||
44 | nvkm_device_pci_preinit(struct nvkm_device *device) | ||
45 | { | ||
46 | struct nvkm_device_pci *pdev = nvkm_device_pci(device); | ||
47 | if (pdev->suspend) { | ||
48 | int ret = pci_enable_device(pdev->pdev); | ||
49 | if (ret) | ||
50 | return ret; | ||
51 | pci_set_master(pdev->pdev); | ||
52 | pdev->suspend = false; | ||
53 | } | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void * | ||
58 | nvkm_device_pci_dtor(struct nvkm_device *device) | ||
59 | { | ||
60 | struct nvkm_device_pci *pdev = nvkm_device_pci(device); | ||
61 | pci_disable_device(pdev->pdev); | ||
62 | return pdev; | ||
63 | } | ||
64 | |||
65 | static const struct nvkm_device_func | ||
66 | nvkm_device_pci_func = { | ||
67 | .pci = nvkm_device_pci, | ||
68 | .dtor = nvkm_device_pci_dtor, | ||
69 | .preinit = nvkm_device_pci_preinit, | ||
70 | .fini = nvkm_device_pci_fini, | ||
71 | }; | ||
72 | |||
73 | int | ||
74 | nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, | ||
75 | bool detect, bool mmio, u64 subdev_mask, | ||
76 | struct nvkm_device **pdevice) | ||
77 | { | ||
78 | struct nvkm_device_pci *pdev; | ||
79 | int ret; | ||
80 | |||
81 | ret = pci_enable_device(pci_dev); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | |||
85 | if (!(pdev = kzalloc(sizeof(*pdev), GFP_KERNEL))) { | ||
86 | pci_disable_device(pci_dev); | ||
87 | return -ENOMEM; | ||
88 | } | ||
89 | *pdevice = &pdev->device; | ||
90 | pdev->pdev = pci_dev; | ||
91 | |||
92 | return nvkm_device_ctor(&nvkm_device_pci_func, NULL, | ||
93 | pci_dev, NVKM_BUS_PCI, | ||
94 | (u64)pci_domain_nr(pci_dev->bus) << 32 | | ||
95 | pci_dev->bus->number << 16 | | ||
96 | PCI_SLOT(pci_dev->devfn) << 8 | | ||
97 | PCI_FUNC(pci_dev->devfn), NULL, | ||
98 | cfg, dbg, detect, mmio, subdev_mask, | ||
99 | &pdev->device); | ||
100 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index 8d3590e7bd87..df9c1550301f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h | |||
@@ -2,6 +2,15 @@ | |||
2 | #define __NVKM_DEVICE_PRIV_H__ | 2 | #define __NVKM_DEVICE_PRIV_H__ |
3 | #include <core/device.h> | 3 | #include <core/device.h> |
4 | 4 | ||
5 | int nvkm_device_ctor(const struct nvkm_device_func *, | ||
6 | const struct nvkm_device_quirk *, | ||
7 | void *, enum nv_bus_type type, u64 handle, | ||
8 | const char *name, const char *cfg, const char *dbg, | ||
9 | bool detect, bool mmio, u64 subdev_mask, | ||
10 | struct nvkm_device *); | ||
11 | int nvkm_device_init(struct nvkm_device *); | ||
12 | int nvkm_device_fini(struct nvkm_device *, bool suspend); | ||
13 | |||
5 | extern struct nvkm_oclass nvkm_control_oclass[]; | 14 | extern struct nvkm_oclass nvkm_control_oclass[]; |
6 | 15 | ||
7 | int nv04_identify(struct nvkm_device *); | 16 | int nv04_identify(struct nvkm_device *); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c new file mode 100644 index 000000000000..0a5e5b88fee2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs <bskeggs@redhat.com> | ||
23 | */ | ||
24 | #include <core/tegra.h> | ||
25 | #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER | ||
26 | #include "priv.h" | ||
27 | |||
28 | static struct nvkm_device_tegra * | ||
29 | nvkm_device_tegra(struct nvkm_device *obj) | ||
30 | { | ||
31 | return container_of(obj, struct nvkm_device_tegra, device); | ||
32 | } | ||
33 | |||
34 | static const struct nvkm_device_func | ||
35 | nvkm_device_tegra_func = { | ||
36 | .tegra = nvkm_device_tegra, | ||
37 | }; | ||
38 | |||
39 | int | ||
40 | nvkm_device_tegra_new(struct platform_device *pdev, | ||
41 | const char *cfg, const char *dbg, | ||
42 | bool detect, bool mmio, u64 subdev_mask, | ||
43 | struct nvkm_device **pdevice) | ||
44 | { | ||
45 | struct nvkm_device_tegra *tdev; | ||
46 | |||
47 | if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) | ||
48 | return -ENOMEM; | ||
49 | *pdevice = &tdev->device; | ||
50 | tdev->pdev = pdev; | ||
51 | |||
52 | return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, pdev, | ||
53 | NVKM_BUS_PLATFORM, pdev->id, NULL, | ||
54 | cfg, dbg, detect, mmio, subdev_mask, | ||
55 | &tdev->device); | ||
56 | } | ||
57 | #else | ||
58 | int | ||
59 | nvkm_device_tegra_new(struct platform_device *pdev, | ||
60 | const char *cfg, const char *dbg, | ||
61 | bool detect, bool mmio, u64 subdev_mask, | ||
62 | struct nvkm_device **pdevice) | ||
63 | { | ||
64 | return -ENOSYS; | ||
65 | } | ||
66 | #endif | ||