diff options
55 files changed, 778 insertions, 377 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index e6e9537537cf..82235f30277c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h | |||
@@ -52,7 +52,7 @@ | |||
52 | #define GM107_DISP /* cl5070.h */ 0x00009470 | 52 | #define GM107_DISP /* cl5070.h */ 0x00009470 |
53 | #define GM200_DISP /* cl5070.h */ 0x00009570 | 53 | #define GM200_DISP /* cl5070.h */ 0x00009570 |
54 | #define GP100_DISP /* cl5070.h */ 0x00009770 | 54 | #define GP100_DISP /* cl5070.h */ 0x00009770 |
55 | #define GP104_DISP /* cl5070.h */ 0x00009870 | 55 | #define GP102_DISP /* cl5070.h */ 0x00009870 |
56 | 56 | ||
57 | #define NV31_MPEG 0x00003174 | 57 | #define NV31_MPEG 0x00003174 |
58 | #define G82_MPEG 0x00008274 | 58 | #define G82_MPEG 0x00008274 |
@@ -90,7 +90,7 @@ | |||
90 | #define GM107_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000947d | 90 | #define GM107_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000947d |
91 | #define GM200_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d | 91 | #define GM200_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d |
92 | #define GP100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000977d | 92 | #define GP100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000977d |
93 | #define GP104_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d | 93 | #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d |
94 | 94 | ||
95 | #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e | 95 | #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e |
96 | #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e | 96 | #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h index d3d26a1e215d..b93f4c1a95e5 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h | |||
@@ -8,5 +8,5 @@ int gk104_ce_new(struct nvkm_device *, int, struct nvkm_engine **); | |||
8 | int gm107_ce_new(struct nvkm_device *, int, struct nvkm_engine **); | 8 | int gm107_ce_new(struct nvkm_device *, int, struct nvkm_engine **); |
9 | int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **); | 9 | int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **); |
10 | int gp100_ce_new(struct nvkm_device *, int, struct nvkm_engine **); | 10 | int gp100_ce_new(struct nvkm_device *, int, struct nvkm_engine **); |
11 | int gp104_ce_new(struct nvkm_device *, int, struct nvkm_engine **); | 11 | int gp102_ce_new(struct nvkm_device *, int, struct nvkm_engine **); |
12 | #endif | 12 | #endif |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h index e82049667ce4..970ae753968a 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h | |||
@@ -33,5 +33,5 @@ int gk110_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | |||
33 | int gm107_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 33 | int gm107_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
34 | int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 34 | int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
35 | int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 35 | int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
36 | int gp104_disp_new(struct nvkm_device *, int, struct nvkm_disp **); | 36 | int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); |
37 | #endif | 37 | #endif |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 65ce79a85d37..794e432578b2 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | |||
@@ -95,7 +95,7 @@ int gm107_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | |||
95 | int gm200_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 95 | int gm200_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
96 | int gm20b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 96 | int gm20b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
97 | int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 97 | int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
98 | int gp104_fb_new(struct nvkm_device *, int, struct nvkm_fb **); | 98 | int gp102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); |
99 | 99 | ||
100 | #include <subdev/bios.h> | 100 | #include <subdev/bios.h> |
101 | #include <subdev/bios/ramcfg.h> | 101 | #include <subdev/bios/ramcfg.h> |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h index e61923d5e49c..f37538eb1fe5 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h | |||
@@ -35,6 +35,8 @@ int gk110_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); | |||
35 | int gk208_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); | 35 | int gk208_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); |
36 | int gk20a_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); | 36 | int gk20a_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); |
37 | int gm107_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); | 37 | int gm107_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); |
38 | int gp100_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); | ||
39 | int gp102_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **); | ||
38 | 40 | ||
39 | /* interface to MEMX process running on PMU */ | 41 | /* interface to MEMX process running on PMU */ |
40 | struct nvkm_memx; | 42 | struct nvkm_memx; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 5698687bc197..bd37ae127582 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <acpi/video.h> | ||
27 | #include <drm/drmP.h> | 28 | #include <drm/drmP.h> |
28 | #include <drm/drm_atomic.h> | 29 | #include <drm/drm_atomic.h> |
29 | #include <drm/drm_atomic_helper.h> | 30 | #include <drm/drm_atomic_helper.h> |
@@ -348,6 +349,55 @@ static struct nouveau_drm_prop_enum_list dither_depth[] = { | |||
348 | } \ | 349 | } \ |
349 | } while(0) | 350 | } while(0) |
350 | 351 | ||
352 | #ifdef CONFIG_ACPI | ||
353 | |||
354 | /* | ||
355 | * Hans de Goede: This define belongs in acpi/video.h, I've submitted a patch | ||
356 | * to the acpi subsys to move it there from drivers/acpi/acpi_video.c . | ||
357 | * This should be dropped once that is merged. | ||
358 | */ | ||
359 | #ifndef ACPI_VIDEO_NOTIFY_PROBE | ||
360 | #define ACPI_VIDEO_NOTIFY_PROBE 0x81 | ||
361 | #endif | ||
362 | |||
363 | static void | ||
364 | nouveau_display_acpi_work(struct work_struct *work) | ||
365 | { | ||
366 | struct nouveau_drm *drm = container_of(work, typeof(*drm), acpi_work); | ||
367 | |||
368 | pm_runtime_get_sync(drm->dev->dev); | ||
369 | |||
370 | drm_helper_hpd_irq_event(drm->dev); | ||
371 | |||
372 | pm_runtime_mark_last_busy(drm->dev->dev); | ||
373 | pm_runtime_put_sync(drm->dev->dev); | ||
374 | } | ||
375 | |||
376 | static int | ||
377 | nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, | ||
378 | void *data) | ||
379 | { | ||
380 | struct nouveau_drm *drm = container_of(nb, typeof(*drm), acpi_nb); | ||
381 | struct acpi_bus_event *info = data; | ||
382 | |||
383 | if (!strcmp(info->device_class, ACPI_VIDEO_CLASS)) { | ||
384 | if (info->type == ACPI_VIDEO_NOTIFY_PROBE) { | ||
385 | /* | ||
386 | * This may be the only indication we receive of a | ||
387 | * connector hotplug on a runtime suspended GPU, | ||
388 | * schedule acpi_work to check. | ||
389 | */ | ||
390 | schedule_work(&drm->acpi_work); | ||
391 | |||
392 | /* acpi-video should not generate keypresses for this */ | ||
393 | return NOTIFY_BAD; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | return NOTIFY_DONE; | ||
398 | } | ||
399 | #endif | ||
400 | |||
351 | int | 401 | int |
352 | nouveau_display_init(struct drm_device *dev) | 402 | nouveau_display_init(struct drm_device *dev) |
353 | { | 403 | { |
@@ -488,7 +538,7 @@ nouveau_display_create(struct drm_device *dev) | |||
488 | 538 | ||
489 | if (nouveau_modeset != 2 && drm->vbios.dcb.entries) { | 539 | if (nouveau_modeset != 2 && drm->vbios.dcb.entries) { |
490 | static const u16 oclass[] = { | 540 | static const u16 oclass[] = { |
491 | GP104_DISP, | 541 | GP102_DISP, |
492 | GP100_DISP, | 542 | GP100_DISP, |
493 | GM200_DISP, | 543 | GM200_DISP, |
494 | GM107_DISP, | 544 | GM107_DISP, |
@@ -532,6 +582,12 @@ nouveau_display_create(struct drm_device *dev) | |||
532 | } | 582 | } |
533 | 583 | ||
534 | nouveau_backlight_init(dev); | 584 | nouveau_backlight_init(dev); |
585 | #ifdef CONFIG_ACPI | ||
586 | INIT_WORK(&drm->acpi_work, nouveau_display_acpi_work); | ||
587 | drm->acpi_nb.notifier_call = nouveau_display_acpi_ntfy; | ||
588 | register_acpi_notifier(&drm->acpi_nb); | ||
589 | #endif | ||
590 | |||
535 | return 0; | 591 | return 0; |
536 | 592 | ||
537 | vblank_err: | 593 | vblank_err: |
@@ -547,6 +603,9 @@ nouveau_display_destroy(struct drm_device *dev) | |||
547 | { | 603 | { |
548 | struct nouveau_display *disp = nouveau_display(dev); | 604 | struct nouveau_display *disp = nouveau_display(dev); |
549 | 605 | ||
606 | #ifdef CONFIG_ACPI | ||
607 | unregister_acpi_notifier(&nouveau_drm(dev)->acpi_nb); | ||
608 | #endif | ||
550 | nouveau_backlight_exit(dev); | 609 | nouveau_backlight_exit(dev); |
551 | nouveau_display_vblank_fini(dev); | 610 | nouveau_display_vblank_fini(dev); |
552 | 611 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 4cd47bae73c7..ae1fd641c96e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -37,6 +37,8 @@ | |||
37 | * - implemented limited ABI16/NVIF interop | 37 | * - implemented limited ABI16/NVIF interop |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/notifier.h> | ||
41 | |||
40 | #include <nvif/client.h> | 42 | #include <nvif/client.h> |
41 | #include <nvif/device.h> | 43 | #include <nvif/device.h> |
42 | #include <nvif/ioctl.h> | 44 | #include <nvif/ioctl.h> |
@@ -161,6 +163,10 @@ struct nouveau_drm { | |||
161 | struct nvbios vbios; | 163 | struct nvbios vbios; |
162 | struct nouveau_display *display; | 164 | struct nouveau_display *display; |
163 | struct backlight_device *backlight; | 165 | struct backlight_device *backlight; |
166 | #ifdef CONFIG_ACPI | ||
167 | struct notifier_block acpi_nb; | ||
168 | struct work_struct acpi_work; | ||
169 | #endif | ||
164 | 170 | ||
165 | /* power management */ | 171 | /* power management */ |
166 | struct nouveau_hwmon *hwmon; | 172 | struct nouveau_hwmon *hwmon; |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a9855a4ec532..22a8b70a4d1e 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -574,7 +574,7 @@ nv50_core_create(struct nvif_device *device, struct nvif_object *disp, | |||
574 | .pushbuf = 0xb0007d00, | 574 | .pushbuf = 0xb0007d00, |
575 | }; | 575 | }; |
576 | static const s32 oclass[] = { | 576 | static const s32 oclass[] = { |
577 | GP104_DISP_CORE_CHANNEL_DMA, | 577 | GP102_DISP_CORE_CHANNEL_DMA, |
578 | GP100_DISP_CORE_CHANNEL_DMA, | 578 | GP100_DISP_CORE_CHANNEL_DMA, |
579 | GM200_DISP_CORE_CHANNEL_DMA, | 579 | GM200_DISP_CORE_CHANNEL_DMA, |
580 | GM107_DISP_CORE_CHANNEL_DMA, | 580 | GM107_DISP_CORE_CHANNEL_DMA, |
@@ -3343,12 +3343,15 @@ nv50_mstm_detect(struct nv50_mstm *mstm, u8 dpcd[8], int allow) | |||
3343 | if (!mstm) | 3343 | if (!mstm) |
3344 | return 0; | 3344 | return 0; |
3345 | 3345 | ||
3346 | if (dpcd[0] >= 0x12 && allow) { | 3346 | if (dpcd[0] >= 0x12) { |
3347 | ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CAP, &dpcd[1]); | 3347 | ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CAP, &dpcd[1]); |
3348 | if (ret < 0) | 3348 | if (ret < 0) |
3349 | return ret; | 3349 | return ret; |
3350 | 3350 | ||
3351 | state = dpcd[1] & DP_MST_CAP; | 3351 | if (!(dpcd[1] & DP_MST_CAP)) |
3352 | dpcd[0] = 0x11; | ||
3353 | else | ||
3354 | state = allow; | ||
3352 | } | 3355 | } |
3353 | 3356 | ||
3354 | ret = nv50_mstm_enable(mstm, dpcd[0], state); | 3357 | ret = nv50_mstm_enable(mstm, dpcd[0], state); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild index a4458a8eb30a..255d81ccf916 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild | |||
@@ -4,4 +4,4 @@ nvkm-y += nvkm/engine/ce/gk104.o | |||
4 | nvkm-y += nvkm/engine/ce/gm107.o | 4 | nvkm-y += nvkm/engine/ce/gm107.o |
5 | nvkm-y += nvkm/engine/ce/gm200.o | 5 | nvkm-y += nvkm/engine/ce/gm200.o |
6 | nvkm-y += nvkm/engine/ce/gp100.o | 6 | nvkm-y += nvkm/engine/ce/gp100.o |
7 | nvkm-y += nvkm/engine/ce/gp104.o | 7 | nvkm-y += nvkm/engine/ce/gp102.o |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gp102.c index 20e019788a53..985c8f653874 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gp102.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <nvif/class.h> | 27 | #include <nvif/class.h> |
28 | 28 | ||
29 | static const struct nvkm_engine_func | 29 | static const struct nvkm_engine_func |
30 | gp104_ce = { | 30 | gp102_ce = { |
31 | .intr = gp100_ce_intr, | 31 | .intr = gp100_ce_intr, |
32 | .sclass = { | 32 | .sclass = { |
33 | { -1, -1, PASCAL_DMA_COPY_B }, | 33 | { -1, -1, PASCAL_DMA_COPY_B }, |
@@ -37,8 +37,8 @@ gp104_ce = { | |||
37 | }; | 37 | }; |
38 | 38 | ||
39 | int | 39 | int |
40 | gp104_ce_new(struct nvkm_device *device, int index, | 40 | gp102_ce_new(struct nvkm_device *device, int index, |
41 | struct nvkm_engine **pengine) | 41 | struct nvkm_engine **pengine) |
42 | { | 42 | { |
43 | return nvkm_engine_new_(&gp104_ce, device, index, true, pengine); | 43 | return nvkm_engine_new_(&gp102_ce, device, index, true, pengine); |
44 | } | 44 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index bd22526edb0b..2cbcffe78c3e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |||
@@ -2167,6 +2167,7 @@ nv130_chipset = { | |||
2167 | .mmu = gf100_mmu_new, | 2167 | .mmu = gf100_mmu_new, |
2168 | .secboot = gm200_secboot_new, | 2168 | .secboot = gm200_secboot_new, |
2169 | .pci = gp100_pci_new, | 2169 | .pci = gp100_pci_new, |
2170 | .pmu = gp100_pmu_new, | ||
2170 | .timer = gk20a_timer_new, | 2171 | .timer = gk20a_timer_new, |
2171 | .top = gk104_top_new, | 2172 | .top = gk104_top_new, |
2172 | .ce[0] = gp100_ce_new, | 2173 | .ce[0] = gp100_ce_new, |
@@ -2183,13 +2184,42 @@ nv130_chipset = { | |||
2183 | }; | 2184 | }; |
2184 | 2185 | ||
2185 | static const struct nvkm_device_chip | 2186 | static const struct nvkm_device_chip |
2187 | nv132_chipset = { | ||
2188 | .name = "GP102", | ||
2189 | .bar = gf100_bar_new, | ||
2190 | .bios = nvkm_bios_new, | ||
2191 | .bus = gf100_bus_new, | ||
2192 | .devinit = gm200_devinit_new, | ||
2193 | .fb = gp102_fb_new, | ||
2194 | .fuse = gm107_fuse_new, | ||
2195 | .gpio = gk104_gpio_new, | ||
2196 | .i2c = gm200_i2c_new, | ||
2197 | .ibus = gm200_ibus_new, | ||
2198 | .imem = nv50_instmem_new, | ||
2199 | .ltc = gp100_ltc_new, | ||
2200 | .mc = gp100_mc_new, | ||
2201 | .mmu = gf100_mmu_new, | ||
2202 | .pci = gp100_pci_new, | ||
2203 | .pmu = gp102_pmu_new, | ||
2204 | .timer = gk20a_timer_new, | ||
2205 | .top = gk104_top_new, | ||
2206 | .ce[0] = gp102_ce_new, | ||
2207 | .ce[1] = gp102_ce_new, | ||
2208 | .ce[2] = gp102_ce_new, | ||
2209 | .ce[3] = gp102_ce_new, | ||
2210 | .disp = gp102_disp_new, | ||
2211 | .dma = gf119_dma_new, | ||
2212 | .fifo = gp100_fifo_new, | ||
2213 | }; | ||
2214 | |||
2215 | static const struct nvkm_device_chip | ||
2186 | nv134_chipset = { | 2216 | nv134_chipset = { |
2187 | .name = "GP104", | 2217 | .name = "GP104", |
2188 | .bar = gf100_bar_new, | 2218 | .bar = gf100_bar_new, |
2189 | .bios = nvkm_bios_new, | 2219 | .bios = nvkm_bios_new, |
2190 | .bus = gf100_bus_new, | 2220 | .bus = gf100_bus_new, |
2191 | .devinit = gm200_devinit_new, | 2221 | .devinit = gm200_devinit_new, |
2192 | .fb = gp104_fb_new, | 2222 | .fb = gp102_fb_new, |
2193 | .fuse = gm107_fuse_new, | 2223 | .fuse = gm107_fuse_new, |
2194 | .gpio = gk104_gpio_new, | 2224 | .gpio = gk104_gpio_new, |
2195 | .i2c = gm200_i2c_new, | 2225 | .i2c = gm200_i2c_new, |
@@ -2199,13 +2229,14 @@ nv134_chipset = { | |||
2199 | .mc = gp100_mc_new, | 2229 | .mc = gp100_mc_new, |
2200 | .mmu = gf100_mmu_new, | 2230 | .mmu = gf100_mmu_new, |
2201 | .pci = gp100_pci_new, | 2231 | .pci = gp100_pci_new, |
2232 | .pmu = gp102_pmu_new, | ||
2202 | .timer = gk20a_timer_new, | 2233 | .timer = gk20a_timer_new, |
2203 | .top = gk104_top_new, | 2234 | .top = gk104_top_new, |
2204 | .ce[0] = gp104_ce_new, | 2235 | .ce[0] = gp102_ce_new, |
2205 | .ce[1] = gp104_ce_new, | 2236 | .ce[1] = gp102_ce_new, |
2206 | .ce[2] = gp104_ce_new, | 2237 | .ce[2] = gp102_ce_new, |
2207 | .ce[3] = gp104_ce_new, | 2238 | .ce[3] = gp102_ce_new, |
2208 | .disp = gp104_disp_new, | 2239 | .disp = gp102_disp_new, |
2209 | .dma = gf119_dma_new, | 2240 | .dma = gf119_dma_new, |
2210 | .fifo = gp100_fifo_new, | 2241 | .fifo = gp100_fifo_new, |
2211 | }; | 2242 | }; |
@@ -2644,6 +2675,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, | |||
2644 | case 0x126: device->chip = &nv126_chipset; break; | 2675 | case 0x126: device->chip = &nv126_chipset; break; |
2645 | case 0x12b: device->chip = &nv12b_chipset; break; | 2676 | case 0x12b: device->chip = &nv12b_chipset; break; |
2646 | case 0x130: device->chip = &nv130_chipset; break; | 2677 | case 0x130: device->chip = &nv130_chipset; break; |
2678 | case 0x132: device->chip = &nv132_chipset; break; | ||
2647 | case 0x134: device->chip = &nv134_chipset; break; | 2679 | case 0x134: device->chip = &nv134_chipset; break; |
2648 | default: | 2680 | default: |
2649 | nvdev_error(device, "unknown chipset (%08x)\n", boot0); | 2681 | nvdev_error(device, "unknown chipset (%08x)\n", boot0); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 0030cd9543b2..74a1ffa425f7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | |||
@@ -1687,7 +1687,7 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, | |||
1687 | * This is necessary for platforms where the default DMA mask of 32 | 1687 | * This is necessary for platforms where the default DMA mask of 32 |
1688 | * does not cover any system memory, i.e., when all RAM is > 4 GB. | 1688 | * does not cover any system memory, i.e., when all RAM is > 4 GB. |
1689 | */ | 1689 | */ |
1690 | if (subdev_mask & BIT(NVKM_SUBDEV_MMU)) | 1690 | if (pdev->device.mmu) |
1691 | dma_set_mask_and_coherent(&pci_dev->dev, | 1691 | dma_set_mask_and_coherent(&pci_dev->dev, |
1692 | DMA_BIT_MASK(pdev->device.mmu->dma_bits)); | 1692 | DMA_BIT_MASK(pdev->device.mmu->dma_bits)); |
1693 | 1693 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 77a52b54a31e..fa05d16ae948 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | |||
@@ -11,7 +11,7 @@ nvkm-y += nvkm/engine/disp/gk110.o | |||
11 | nvkm-y += nvkm/engine/disp/gm107.o | 11 | nvkm-y += nvkm/engine/disp/gm107.o |
12 | nvkm-y += nvkm/engine/disp/gm200.o | 12 | nvkm-y += nvkm/engine/disp/gm200.o |
13 | nvkm-y += nvkm/engine/disp/gp100.o | 13 | nvkm-y += nvkm/engine/disp/gp100.o |
14 | nvkm-y += nvkm/engine/disp/gp104.o | 14 | nvkm-y += nvkm/engine/disp/gp102.o |
15 | 15 | ||
16 | nvkm-y += nvkm/engine/disp/outp.o | 16 | nvkm-y += nvkm/engine/disp/outp.o |
17 | nvkm-y += nvkm/engine/disp/outpdp.o | 17 | nvkm-y += nvkm/engine/disp/outpdp.o |
@@ -48,14 +48,14 @@ nvkm-y += nvkm/engine/disp/rootgk110.o | |||
48 | nvkm-y += nvkm/engine/disp/rootgm107.o | 48 | nvkm-y += nvkm/engine/disp/rootgm107.o |
49 | nvkm-y += nvkm/engine/disp/rootgm200.o | 49 | nvkm-y += nvkm/engine/disp/rootgm200.o |
50 | nvkm-y += nvkm/engine/disp/rootgp100.o | 50 | nvkm-y += nvkm/engine/disp/rootgp100.o |
51 | nvkm-y += nvkm/engine/disp/rootgp104.o | 51 | nvkm-y += nvkm/engine/disp/rootgp102.o |
52 | 52 | ||
53 | nvkm-y += nvkm/engine/disp/channv50.o | 53 | nvkm-y += nvkm/engine/disp/channv50.o |
54 | nvkm-y += nvkm/engine/disp/changf119.o | 54 | nvkm-y += nvkm/engine/disp/changf119.o |
55 | 55 | ||
56 | nvkm-y += nvkm/engine/disp/dmacnv50.o | 56 | nvkm-y += nvkm/engine/disp/dmacnv50.o |
57 | nvkm-y += nvkm/engine/disp/dmacgf119.o | 57 | nvkm-y += nvkm/engine/disp/dmacgf119.o |
58 | nvkm-y += nvkm/engine/disp/dmacgp104.o | 58 | nvkm-y += nvkm/engine/disp/dmacgp102.o |
59 | 59 | ||
60 | nvkm-y += nvkm/engine/disp/basenv50.o | 60 | nvkm-y += nvkm/engine/disp/basenv50.o |
61 | nvkm-y += nvkm/engine/disp/baseg84.o | 61 | nvkm-y += nvkm/engine/disp/baseg84.o |
@@ -64,7 +64,7 @@ nvkm-y += nvkm/engine/disp/basegt215.o | |||
64 | nvkm-y += nvkm/engine/disp/basegf119.o | 64 | nvkm-y += nvkm/engine/disp/basegf119.o |
65 | nvkm-y += nvkm/engine/disp/basegk104.o | 65 | nvkm-y += nvkm/engine/disp/basegk104.o |
66 | nvkm-y += nvkm/engine/disp/basegk110.o | 66 | nvkm-y += nvkm/engine/disp/basegk110.o |
67 | nvkm-y += nvkm/engine/disp/basegp104.o | 67 | nvkm-y += nvkm/engine/disp/basegp102.o |
68 | 68 | ||
69 | nvkm-y += nvkm/engine/disp/corenv50.o | 69 | nvkm-y += nvkm/engine/disp/corenv50.o |
70 | nvkm-y += nvkm/engine/disp/coreg84.o | 70 | nvkm-y += nvkm/engine/disp/coreg84.o |
@@ -77,7 +77,7 @@ nvkm-y += nvkm/engine/disp/coregk110.o | |||
77 | nvkm-y += nvkm/engine/disp/coregm107.o | 77 | nvkm-y += nvkm/engine/disp/coregm107.o |
78 | nvkm-y += nvkm/engine/disp/coregm200.o | 78 | nvkm-y += nvkm/engine/disp/coregm200.o |
79 | nvkm-y += nvkm/engine/disp/coregp100.o | 79 | nvkm-y += nvkm/engine/disp/coregp100.o |
80 | nvkm-y += nvkm/engine/disp/coregp104.o | 80 | nvkm-y += nvkm/engine/disp/coregp102.o |
81 | 81 | ||
82 | nvkm-y += nvkm/engine/disp/ovlynv50.o | 82 | nvkm-y += nvkm/engine/disp/ovlynv50.o |
83 | nvkm-y += nvkm/engine/disp/ovlyg84.o | 83 | nvkm-y += nvkm/engine/disp/ovlyg84.o |
@@ -85,7 +85,7 @@ nvkm-y += nvkm/engine/disp/ovlygt200.o | |||
85 | nvkm-y += nvkm/engine/disp/ovlygt215.o | 85 | nvkm-y += nvkm/engine/disp/ovlygt215.o |
86 | nvkm-y += nvkm/engine/disp/ovlygf119.o | 86 | nvkm-y += nvkm/engine/disp/ovlygf119.o |
87 | nvkm-y += nvkm/engine/disp/ovlygk104.o | 87 | nvkm-y += nvkm/engine/disp/ovlygk104.o |
88 | nvkm-y += nvkm/engine/disp/ovlygp104.o | 88 | nvkm-y += nvkm/engine/disp/ovlygp102.o |
89 | 89 | ||
90 | nvkm-y += nvkm/engine/disp/piocnv50.o | 90 | nvkm-y += nvkm/engine/disp/piocnv50.o |
91 | nvkm-y += nvkm/engine/disp/piocgf119.o | 91 | nvkm-y += nvkm/engine/disp/piocgf119.o |
@@ -95,9 +95,11 @@ nvkm-y += nvkm/engine/disp/cursg84.o | |||
95 | nvkm-y += nvkm/engine/disp/cursgt215.o | 95 | nvkm-y += nvkm/engine/disp/cursgt215.o |
96 | nvkm-y += nvkm/engine/disp/cursgf119.o | 96 | nvkm-y += nvkm/engine/disp/cursgf119.o |
97 | nvkm-y += nvkm/engine/disp/cursgk104.o | 97 | nvkm-y += nvkm/engine/disp/cursgk104.o |
98 | nvkm-y += nvkm/engine/disp/cursgp102.o | ||
98 | 99 | ||
99 | nvkm-y += nvkm/engine/disp/oimmnv50.o | 100 | nvkm-y += nvkm/engine/disp/oimmnv50.o |
100 | nvkm-y += nvkm/engine/disp/oimmg84.o | 101 | nvkm-y += nvkm/engine/disp/oimmg84.o |
101 | nvkm-y += nvkm/engine/disp/oimmgt215.o | 102 | nvkm-y += nvkm/engine/disp/oimmgt215.o |
102 | nvkm-y += nvkm/engine/disp/oimmgf119.o | 103 | nvkm-y += nvkm/engine/disp/oimmgf119.o |
103 | nvkm-y += nvkm/engine/disp/oimmgk104.o | 104 | nvkm-y += nvkm/engine/disp/oimmgk104.o |
105 | nvkm-y += nvkm/engine/disp/oimmgp102.o | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c index 51688e37c54e..8a3cdeef8d2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c | |||
@@ -27,12 +27,12 @@ | |||
27 | #include <nvif/class.h> | 27 | #include <nvif/class.h> |
28 | 28 | ||
29 | const struct nv50_disp_dmac_oclass | 29 | const struct nv50_disp_dmac_oclass |
30 | gp104_disp_base_oclass = { | 30 | gp102_disp_base_oclass = { |
31 | .base.oclass = GK110_DISP_BASE_CHANNEL_DMA, | 31 | .base.oclass = GK110_DISP_BASE_CHANNEL_DMA, |
32 | .base.minver = 0, | 32 | .base.minver = 0, |
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_base_new, | 34 | .ctor = nv50_disp_base_new, |
35 | .func = &gp104_disp_dmac_func, | 35 | .func = &gp102_disp_dmac_func, |
36 | .mthd = &gf119_disp_base_chan_mthd, | 36 | .mthd = &gf119_disp_base_chan_mthd, |
37 | .chid = 1, | 37 | .chid = 1, |
38 | }; | 38 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 26990d44ae75..524a24eae1a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c | |||
@@ -82,7 +82,7 @@ nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug) | |||
82 | 82 | ||
83 | if (mthd->addr) { | 83 | if (mthd->addr) { |
84 | snprintf(cname_, sizeof(cname_), "%s %d", | 84 | snprintf(cname_, sizeof(cname_), "%s %d", |
85 | mthd->name, chan->chid); | 85 | mthd->name, chan->chid.user); |
86 | cname = cname_; | 86 | cname = cname_; |
87 | } | 87 | } |
88 | 88 | ||
@@ -139,7 +139,7 @@ nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size, | |||
139 | if (!(ret = nvif_unvers(ret, &data, &size, args->none))) { | 139 | if (!(ret = nvif_unvers(ret, &data, &size, args->none))) { |
140 | notify->size = sizeof(struct nvif_notify_uevent_rep); | 140 | notify->size = sizeof(struct nvif_notify_uevent_rep); |
141 | notify->types = 1; | 141 | notify->types = 1; |
142 | notify->index = chan->chid; | 142 | notify->index = chan->chid.user; |
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
@@ -159,7 +159,7 @@ nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data) | |||
159 | struct nv50_disp_chan *chan = nv50_disp_chan(object); | 159 | struct nv50_disp_chan *chan = nv50_disp_chan(object); |
160 | struct nv50_disp *disp = chan->root->disp; | 160 | struct nv50_disp *disp = chan->root->disp; |
161 | struct nvkm_device *device = disp->base.engine.subdev.device; | 161 | struct nvkm_device *device = disp->base.engine.subdev.device; |
162 | *data = nvkm_rd32(device, 0x640000 + (chan->chid * 0x1000) + addr); | 162 | *data = nvkm_rd32(device, 0x640000 + (chan->chid.user * 0x1000) + addr); |
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
@@ -169,7 +169,7 @@ nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data) | |||
169 | struct nv50_disp_chan *chan = nv50_disp_chan(object); | 169 | struct nv50_disp_chan *chan = nv50_disp_chan(object); |
170 | struct nv50_disp *disp = chan->root->disp; | 170 | struct nv50_disp *disp = chan->root->disp; |
171 | struct nvkm_device *device = disp->base.engine.subdev.device; | 171 | struct nvkm_device *device = disp->base.engine.subdev.device; |
172 | nvkm_wr32(device, 0x640000 + (chan->chid * 0x1000) + addr, data); | 172 | nvkm_wr32(device, 0x640000 + (chan->chid.user * 0x1000) + addr, data); |
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
175 | 175 | ||
@@ -196,7 +196,7 @@ nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size) | |||
196 | struct nv50_disp *disp = chan->root->disp; | 196 | struct nv50_disp *disp = chan->root->disp; |
197 | struct nvkm_device *device = disp->base.engine.subdev.device; | 197 | struct nvkm_device *device = disp->base.engine.subdev.device; |
198 | *addr = device->func->resource_addr(device, 0) + | 198 | *addr = device->func->resource_addr(device, 0) + |
199 | 0x640000 + (chan->chid * 0x1000); | 199 | 0x640000 + (chan->chid.user * 0x1000); |
200 | *size = 0x001000; | 200 | *size = 0x001000; |
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
@@ -243,8 +243,8 @@ nv50_disp_chan_dtor(struct nvkm_object *object) | |||
243 | { | 243 | { |
244 | struct nv50_disp_chan *chan = nv50_disp_chan(object); | 244 | struct nv50_disp_chan *chan = nv50_disp_chan(object); |
245 | struct nv50_disp *disp = chan->root->disp; | 245 | struct nv50_disp *disp = chan->root->disp; |
246 | if (chan->chid >= 0) | 246 | if (chan->chid.user >= 0) |
247 | disp->chan[chan->chid] = NULL; | 247 | disp->chan[chan->chid.user] = NULL; |
248 | return chan->func->dtor ? chan->func->dtor(chan) : chan; | 248 | return chan->func->dtor ? chan->func->dtor(chan) : chan; |
249 | } | 249 | } |
250 | 250 | ||
@@ -263,7 +263,7 @@ nv50_disp_chan = { | |||
263 | int | 263 | int |
264 | nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, | 264 | nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, |
265 | const struct nv50_disp_chan_mthd *mthd, | 265 | const struct nv50_disp_chan_mthd *mthd, |
266 | struct nv50_disp_root *root, int chid, int head, | 266 | struct nv50_disp_root *root, int ctrl, int user, int head, |
267 | const struct nvkm_oclass *oclass, | 267 | const struct nvkm_oclass *oclass, |
268 | struct nv50_disp_chan *chan) | 268 | struct nv50_disp_chan *chan) |
269 | { | 269 | { |
@@ -273,21 +273,22 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, | |||
273 | chan->func = func; | 273 | chan->func = func; |
274 | chan->mthd = mthd; | 274 | chan->mthd = mthd; |
275 | chan->root = root; | 275 | chan->root = root; |
276 | chan->chid = chid; | 276 | chan->chid.ctrl = ctrl; |
277 | chan->chid.user = user; | ||
277 | chan->head = head; | 278 | chan->head = head; |
278 | 279 | ||
279 | if (disp->chan[chan->chid]) { | 280 | if (disp->chan[chan->chid.user]) { |
280 | chan->chid = -1; | 281 | chan->chid.user = -1; |
281 | return -EBUSY; | 282 | return -EBUSY; |
282 | } | 283 | } |
283 | disp->chan[chan->chid] = chan; | 284 | disp->chan[chan->chid.user] = chan; |
284 | return 0; | 285 | return 0; |
285 | } | 286 | } |
286 | 287 | ||
287 | int | 288 | int |
288 | nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, | 289 | nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, |
289 | const struct nv50_disp_chan_mthd *mthd, | 290 | const struct nv50_disp_chan_mthd *mthd, |
290 | struct nv50_disp_root *root, int chid, int head, | 291 | struct nv50_disp_root *root, int ctrl, int user, int head, |
291 | const struct nvkm_oclass *oclass, | 292 | const struct nvkm_oclass *oclass, |
292 | struct nvkm_object **pobject) | 293 | struct nvkm_object **pobject) |
293 | { | 294 | { |
@@ -297,5 +298,6 @@ nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, | |||
297 | return -ENOMEM; | 298 | return -ENOMEM; |
298 | *pobject = &chan->object; | 299 | *pobject = &chan->object; |
299 | 300 | ||
300 | return nv50_disp_chan_ctor(func, mthd, root, chid, head, oclass, chan); | 301 | return nv50_disp_chan_ctor(func, mthd, root, ctrl, user, |
302 | head, oclass, chan); | ||
301 | } | 303 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index f5f683d9fd20..737b38f6fbd2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h | |||
@@ -7,7 +7,11 @@ struct nv50_disp_chan { | |||
7 | const struct nv50_disp_chan_func *func; | 7 | const struct nv50_disp_chan_func *func; |
8 | const struct nv50_disp_chan_mthd *mthd; | 8 | const struct nv50_disp_chan_mthd *mthd; |
9 | struct nv50_disp_root *root; | 9 | struct nv50_disp_root *root; |
10 | int chid; | 10 | |
11 | struct { | ||
12 | int ctrl; | ||
13 | int user; | ||
14 | } chid; | ||
11 | int head; | 15 | int head; |
12 | 16 | ||
13 | struct nvkm_object object; | 17 | struct nvkm_object object; |
@@ -25,11 +29,11 @@ struct nv50_disp_chan_func { | |||
25 | 29 | ||
26 | int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *, | 30 | int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *, |
27 | const struct nv50_disp_chan_mthd *, | 31 | const struct nv50_disp_chan_mthd *, |
28 | struct nv50_disp_root *, int chid, int head, | 32 | struct nv50_disp_root *, int ctrl, int user, int head, |
29 | const struct nvkm_oclass *, struct nv50_disp_chan *); | 33 | const struct nvkm_oclass *, struct nv50_disp_chan *); |
30 | int nv50_disp_chan_new_(const struct nv50_disp_chan_func *, | 34 | int nv50_disp_chan_new_(const struct nv50_disp_chan_func *, |
31 | const struct nv50_disp_chan_mthd *, | 35 | const struct nv50_disp_chan_mthd *, |
32 | struct nv50_disp_root *, int chid, int head, | 36 | struct nv50_disp_root *, int ctrl, int user, int head, |
33 | const struct nvkm_oclass *, struct nvkm_object **); | 37 | const struct nvkm_oclass *, struct nvkm_object **); |
34 | 38 | ||
35 | extern const struct nv50_disp_chan_func nv50_disp_pioc_func; | 39 | extern const struct nv50_disp_chan_func nv50_disp_pioc_func; |
@@ -90,13 +94,16 @@ extern const struct nv50_disp_chan_mthd gk104_disp_ovly_chan_mthd; | |||
90 | struct nv50_disp_pioc_oclass { | 94 | struct nv50_disp_pioc_oclass { |
91 | int (*ctor)(const struct nv50_disp_chan_func *, | 95 | int (*ctor)(const struct nv50_disp_chan_func *, |
92 | const struct nv50_disp_chan_mthd *, | 96 | const struct nv50_disp_chan_mthd *, |
93 | struct nv50_disp_root *, int chid, | 97 | struct nv50_disp_root *, int ctrl, int user, |
94 | const struct nvkm_oclass *, void *data, u32 size, | 98 | const struct nvkm_oclass *, void *data, u32 size, |
95 | struct nvkm_object **); | 99 | struct nvkm_object **); |
96 | struct nvkm_sclass base; | 100 | struct nvkm_sclass base; |
97 | const struct nv50_disp_chan_func *func; | 101 | const struct nv50_disp_chan_func *func; |
98 | const struct nv50_disp_chan_mthd *mthd; | 102 | const struct nv50_disp_chan_mthd *mthd; |
99 | int chid; | 103 | struct { |
104 | int ctrl; | ||
105 | int user; | ||
106 | } chid; | ||
100 | }; | 107 | }; |
101 | 108 | ||
102 | extern const struct nv50_disp_pioc_oclass nv50_disp_oimm_oclass; | 109 | extern const struct nv50_disp_pioc_oclass nv50_disp_oimm_oclass; |
@@ -114,15 +121,17 @@ extern const struct nv50_disp_pioc_oclass gf119_disp_curs_oclass; | |||
114 | extern const struct nv50_disp_pioc_oclass gk104_disp_oimm_oclass; | 121 | extern const struct nv50_disp_pioc_oclass gk104_disp_oimm_oclass; |
115 | extern const struct nv50_disp_pioc_oclass gk104_disp_curs_oclass; | 122 | extern const struct nv50_disp_pioc_oclass gk104_disp_curs_oclass; |
116 | 123 | ||
124 | extern const struct nv50_disp_pioc_oclass gp102_disp_oimm_oclass; | ||
125 | extern const struct nv50_disp_pioc_oclass gp102_disp_curs_oclass; | ||
117 | 126 | ||
118 | int nv50_disp_curs_new(const struct nv50_disp_chan_func *, | 127 | int nv50_disp_curs_new(const struct nv50_disp_chan_func *, |
119 | const struct nv50_disp_chan_mthd *, | 128 | const struct nv50_disp_chan_mthd *, |
120 | struct nv50_disp_root *, int chid, | 129 | struct nv50_disp_root *, int ctrl, int user, |
121 | const struct nvkm_oclass *, void *data, u32 size, | 130 | const struct nvkm_oclass *, void *data, u32 size, |
122 | struct nvkm_object **); | 131 | struct nvkm_object **); |
123 | int nv50_disp_oimm_new(const struct nv50_disp_chan_func *, | 132 | int nv50_disp_oimm_new(const struct nv50_disp_chan_func *, |
124 | const struct nv50_disp_chan_mthd *, | 133 | const struct nv50_disp_chan_mthd *, |
125 | struct nv50_disp_root *, int chid, | 134 | struct nv50_disp_root *, int ctrl, int user, |
126 | const struct nvkm_oclass *, void *data, u32 size, | 135 | const struct nvkm_oclass *, void *data, u32 size, |
127 | struct nvkm_object **); | 136 | struct nvkm_object **); |
128 | #endif | 137 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c index e356f87fbe60..b0df4b752b8c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <nvif/class.h> | 29 | #include <nvif/class.h> |
30 | 30 | ||
31 | static int | 31 | static int |
32 | gp104_disp_core_init(struct nv50_disp_dmac *chan) | 32 | gp102_disp_core_init(struct nv50_disp_dmac *chan) |
33 | { | 33 | { |
34 | struct nv50_disp *disp = chan->base.root->disp; | 34 | struct nv50_disp *disp = chan->base.root->disp; |
35 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 35 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
@@ -60,19 +60,19 @@ gp104_disp_core_init(struct nv50_disp_dmac *chan) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | static const struct nv50_disp_dmac_func | 62 | static const struct nv50_disp_dmac_func |
63 | gp104_disp_core_func = { | 63 | gp102_disp_core_func = { |
64 | .init = gp104_disp_core_init, | 64 | .init = gp102_disp_core_init, |
65 | .fini = gf119_disp_core_fini, | 65 | .fini = gf119_disp_core_fini, |
66 | .bind = gf119_disp_dmac_bind, | 66 | .bind = gf119_disp_dmac_bind, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | const struct nv50_disp_dmac_oclass | 69 | const struct nv50_disp_dmac_oclass |
70 | gp104_disp_core_oclass = { | 70 | gp102_disp_core_oclass = { |
71 | .base.oclass = GP104_DISP_CORE_CHANNEL_DMA, | 71 | .base.oclass = GP102_DISP_CORE_CHANNEL_DMA, |
72 | .base.minver = 0, | 72 | .base.minver = 0, |
73 | .base.maxver = 0, | 73 | .base.maxver = 0, |
74 | .ctor = nv50_disp_core_new, | 74 | .ctor = nv50_disp_core_new, |
75 | .func = &gp104_disp_core_func, | 75 | .func = &gp102_disp_core_func, |
76 | .mthd = &gk104_disp_core_chan_mthd, | 76 | .mthd = &gk104_disp_core_chan_mthd, |
77 | .chid = 0, | 77 | .chid = 0, |
78 | }; | 78 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c index dd99fc7060b1..fa781b5a7e07 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c | |||
@@ -33,5 +33,5 @@ g84_disp_curs_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_curs_new, | 34 | .ctor = nv50_disp_curs_new, |
35 | .func = &nv50_disp_pioc_func, | 35 | .func = &nv50_disp_pioc_func, |
36 | .chid = 7, | 36 | .chid = { 7, 7 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c index 2a1574e06ad6..2be6fb052c65 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c | |||
@@ -33,5 +33,5 @@ gf119_disp_curs_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_curs_new, | 34 | .ctor = nv50_disp_curs_new, |
35 | .func = &gf119_disp_pioc_func, | 35 | .func = &gf119_disp_pioc_func, |
36 | .chid = 13, | 36 | .chid = { 13, 13 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c index 28e8f06c9472..2a99db4bf8f8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c | |||
@@ -33,5 +33,5 @@ gk104_disp_curs_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_curs_new, | 34 | .ctor = nv50_disp_curs_new, |
35 | .func = &gf119_disp_pioc_func, | 35 | .func = &gf119_disp_pioc_func, |
36 | .chid = 13, | 36 | .chid = { 13, 13 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c new file mode 100644 index 000000000000..e958210d8105 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright 2016 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 "channv50.h" | ||
25 | #include "rootnv50.h" | ||
26 | |||
27 | #include <nvif/class.h> | ||
28 | |||
29 | const struct nv50_disp_pioc_oclass | ||
30 | gp102_disp_curs_oclass = { | ||
31 | .base.oclass = GK104_DISP_CURSOR, | ||
32 | .base.minver = 0, | ||
33 | .base.maxver = 0, | ||
34 | .ctor = nv50_disp_curs_new, | ||
35 | .func = &gf119_disp_pioc_func, | ||
36 | .chid = { 13, 17 }, | ||
37 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c index d8a4b9ca139c..00a7f3564450 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c | |||
@@ -33,5 +33,5 @@ gt215_disp_curs_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_curs_new, | 34 | .ctor = nv50_disp_curs_new, |
35 | .func = &nv50_disp_pioc_func, | 35 | .func = &nv50_disp_pioc_func, |
36 | .chid = 7, | 36 | .chid = { 7, 7 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c index 8b1320499a0f..82ff82d8c1ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c | |||
@@ -33,7 +33,7 @@ | |||
33 | int | 33 | int |
34 | nv50_disp_curs_new(const struct nv50_disp_chan_func *func, | 34 | nv50_disp_curs_new(const struct nv50_disp_chan_func *func, |
35 | const struct nv50_disp_chan_mthd *mthd, | 35 | const struct nv50_disp_chan_mthd *mthd, |
36 | struct nv50_disp_root *root, int chid, | 36 | struct nv50_disp_root *root, int ctrl, int user, |
37 | const struct nvkm_oclass *oclass, void *data, u32 size, | 37 | const struct nvkm_oclass *oclass, void *data, u32 size, |
38 | struct nvkm_object **pobject) | 38 | struct nvkm_object **pobject) |
39 | { | 39 | { |
@@ -54,7 +54,7 @@ nv50_disp_curs_new(const struct nv50_disp_chan_func *func, | |||
54 | } else | 54 | } else |
55 | return ret; | 55 | return ret; |
56 | 56 | ||
57 | return nv50_disp_chan_new_(func, mthd, root, chid + head, | 57 | return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head, |
58 | head, oclass, pobject); | 58 | head, oclass, pobject); |
59 | } | 59 | } |
60 | 60 | ||
@@ -65,5 +65,5 @@ nv50_disp_curs_oclass = { | |||
65 | .base.maxver = 0, | 65 | .base.maxver = 0, |
66 | .ctor = nv50_disp_curs_new, | 66 | .ctor = nv50_disp_curs_new, |
67 | .func = &nv50_disp_pioc_func, | 67 | .func = &nv50_disp_pioc_func, |
68 | .chid = 7, | 68 | .chid = { 7, 7 }, |
69 | }; | 69 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c index a57f7cef307a..ce7cd74fbd5d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c | |||
@@ -32,8 +32,8 @@ gf119_disp_dmac_bind(struct nv50_disp_dmac *chan, | |||
32 | struct nvkm_object *object, u32 handle) | 32 | struct nvkm_object *object, u32 handle) |
33 | { | 33 | { |
34 | return nvkm_ramht_insert(chan->base.root->ramht, object, | 34 | return nvkm_ramht_insert(chan->base.root->ramht, object, |
35 | chan->base.chid, -9, handle, | 35 | chan->base.chid.user, -9, handle, |
36 | chan->base.chid << 27 | 0x00000001); | 36 | chan->base.chid.user << 27 | 0x00000001); |
37 | } | 37 | } |
38 | 38 | ||
39 | void | 39 | void |
@@ -42,22 +42,23 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan) | |||
42 | struct nv50_disp *disp = chan->base.root->disp; | 42 | struct nv50_disp *disp = chan->base.root->disp; |
43 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 43 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
44 | struct nvkm_device *device = subdev->device; | 44 | struct nvkm_device *device = subdev->device; |
45 | int chid = chan->base.chid; | 45 | int ctrl = chan->base.chid.ctrl; |
46 | int user = chan->base.chid.user; | ||
46 | 47 | ||
47 | /* deactivate channel */ | 48 | /* deactivate channel */ |
48 | nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00001010, 0x00001000); | 49 | nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000); |
49 | nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000003, 0x00000000); | 50 | nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000003, 0x00000000); |
50 | if (nvkm_msec(device, 2000, | 51 | if (nvkm_msec(device, 2000, |
51 | if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x001e0000)) | 52 | if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x001e0000)) |
52 | break; | 53 | break; |
53 | ) < 0) { | 54 | ) < 0) { |
54 | nvkm_error(subdev, "ch %d fini: %08x\n", chid, | 55 | nvkm_error(subdev, "ch %d fini: %08x\n", user, |
55 | nvkm_rd32(device, 0x610490 + (chid * 0x10))); | 56 | nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); |
56 | } | 57 | } |
57 | 58 | ||
58 | /* disable error reporting and completion notification */ | 59 | /* disable error reporting and completion notification */ |
59 | nvkm_mask(device, 0x610090, 0x00000001 << chid, 0x00000000); | 60 | nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000); |
60 | nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000000); | 61 | nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000); |
61 | } | 62 | } |
62 | 63 | ||
63 | static int | 64 | static int |
@@ -66,26 +67,27 @@ gf119_disp_dmac_init(struct nv50_disp_dmac *chan) | |||
66 | struct nv50_disp *disp = chan->base.root->disp; | 67 | struct nv50_disp *disp = chan->base.root->disp; |
67 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 68 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
68 | struct nvkm_device *device = subdev->device; | 69 | struct nvkm_device *device = subdev->device; |
69 | int chid = chan->base.chid; | 70 | int ctrl = chan->base.chid.ctrl; |
71 | int user = chan->base.chid.user; | ||
70 | 72 | ||
71 | /* enable error reporting */ | 73 | /* enable error reporting */ |
72 | nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid); | 74 | nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); |
73 | 75 | ||
74 | /* initialise channel for dma command submission */ | 76 | /* initialise channel for dma command submission */ |
75 | nvkm_wr32(device, 0x610494 + (chid * 0x0010), chan->push); | 77 | nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push); |
76 | nvkm_wr32(device, 0x610498 + (chid * 0x0010), 0x00010000); | 78 | nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000); |
77 | nvkm_wr32(device, 0x61049c + (chid * 0x0010), 0x00000001); | 79 | nvkm_wr32(device, 0x61049c + (ctrl * 0x0010), 0x00000001); |
78 | nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010); | 80 | nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010); |
79 | nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000); | 81 | nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000); |
80 | nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013); | 82 | nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013); |
81 | 83 | ||
82 | /* wait for it to go inactive */ | 84 | /* wait for it to go inactive */ |
83 | if (nvkm_msec(device, 2000, | 85 | if (nvkm_msec(device, 2000, |
84 | if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000)) | 86 | if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000)) |
85 | break; | 87 | break; |
86 | ) < 0) { | 88 | ) < 0) { |
87 | nvkm_error(subdev, "ch %d init: %08x\n", chid, | 89 | nvkm_error(subdev, "ch %d init: %08x\n", user, |
88 | nvkm_rd32(device, 0x610490 + (chid * 0x10))); | 90 | nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); |
89 | return -EBUSY; | 91 | return -EBUSY; |
90 | } | 92 | } |
91 | 93 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c index ad24c2c57696..cdead9500343 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c | |||
@@ -27,31 +27,32 @@ | |||
27 | #include <subdev/timer.h> | 27 | #include <subdev/timer.h> |
28 | 28 | ||
29 | static int | 29 | static int |
30 | gp104_disp_dmac_init(struct nv50_disp_dmac *chan) | 30 | gp102_disp_dmac_init(struct nv50_disp_dmac *chan) |
31 | { | 31 | { |
32 | struct nv50_disp *disp = chan->base.root->disp; | 32 | struct nv50_disp *disp = chan->base.root->disp; |
33 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 33 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
34 | struct nvkm_device *device = subdev->device; | 34 | struct nvkm_device *device = subdev->device; |
35 | int chid = chan->base.chid; | 35 | int ctrl = chan->base.chid.ctrl; |
36 | int user = chan->base.chid.user; | ||
36 | 37 | ||
37 | /* enable error reporting */ | 38 | /* enable error reporting */ |
38 | nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid); | 39 | nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); |
39 | 40 | ||
40 | /* initialise channel for dma command submission */ | 41 | /* initialise channel for dma command submission */ |
41 | nvkm_wr32(device, 0x611494 + (chid * 0x0010), chan->push); | 42 | nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push); |
42 | nvkm_wr32(device, 0x611498 + (chid * 0x0010), 0x00010000); | 43 | nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000); |
43 | nvkm_wr32(device, 0x61149c + (chid * 0x0010), 0x00000001); | 44 | nvkm_wr32(device, 0x61149c + (ctrl * 0x0010), 0x00000001); |
44 | nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010); | 45 | nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010); |
45 | nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000); | 46 | nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000); |
46 | nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013); | 47 | nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013); |
47 | 48 | ||
48 | /* wait for it to go inactive */ | 49 | /* wait for it to go inactive */ |
49 | if (nvkm_msec(device, 2000, | 50 | if (nvkm_msec(device, 2000, |
50 | if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000)) | 51 | if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000)) |
51 | break; | 52 | break; |
52 | ) < 0) { | 53 | ) < 0) { |
53 | nvkm_error(subdev, "ch %d init: %08x\n", chid, | 54 | nvkm_error(subdev, "ch %d init: %08x\n", user, |
54 | nvkm_rd32(device, 0x610490 + (chid * 0x10))); | 55 | nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); |
55 | return -EBUSY; | 56 | return -EBUSY; |
56 | } | 57 | } |
57 | 58 | ||
@@ -59,8 +60,8 @@ gp104_disp_dmac_init(struct nv50_disp_dmac *chan) | |||
59 | } | 60 | } |
60 | 61 | ||
61 | const struct nv50_disp_dmac_func | 62 | const struct nv50_disp_dmac_func |
62 | gp104_disp_dmac_func = { | 63 | gp102_disp_dmac_func = { |
63 | .init = gp104_disp_dmac_init, | 64 | .init = gp102_disp_dmac_init, |
64 | .fini = gf119_disp_dmac_fini, | 65 | .fini = gf119_disp_dmac_fini, |
65 | .bind = gf119_disp_dmac_bind, | 66 | .bind = gf119_disp_dmac_bind, |
66 | }; | 67 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index 9c6645a357b9..0a1381a84552 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c | |||
@@ -149,7 +149,7 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func, | |||
149 | chan->func = func; | 149 | chan->func = func; |
150 | 150 | ||
151 | ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, root, | 151 | ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, root, |
152 | chid, head, oclass, &chan->base); | 152 | chid, chid, head, oclass, &chan->base); |
153 | if (ret) | 153 | if (ret) |
154 | return ret; | 154 | return ret; |
155 | 155 | ||
@@ -179,9 +179,9 @@ nv50_disp_dmac_bind(struct nv50_disp_dmac *chan, | |||
179 | struct nvkm_object *object, u32 handle) | 179 | struct nvkm_object *object, u32 handle) |
180 | { | 180 | { |
181 | return nvkm_ramht_insert(chan->base.root->ramht, object, | 181 | return nvkm_ramht_insert(chan->base.root->ramht, object, |
182 | chan->base.chid, -10, handle, | 182 | chan->base.chid.user, -10, handle, |
183 | chan->base.chid << 28 | | 183 | chan->base.chid.user << 28 | |
184 | chan->base.chid); | 184 | chan->base.chid.user); |
185 | } | 185 | } |
186 | 186 | ||
187 | static void | 187 | static void |
@@ -190,21 +190,22 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan) | |||
190 | struct nv50_disp *disp = chan->base.root->disp; | 190 | struct nv50_disp *disp = chan->base.root->disp; |
191 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 191 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
192 | struct nvkm_device *device = subdev->device; | 192 | struct nvkm_device *device = subdev->device; |
193 | int chid = chan->base.chid; | 193 | int ctrl = chan->base.chid.ctrl; |
194 | int user = chan->base.chid.user; | ||
194 | 195 | ||
195 | /* deactivate channel */ | 196 | /* deactivate channel */ |
196 | nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000); | 197 | nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000); |
197 | nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000); | 198 | nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000003, 0x00000000); |
198 | if (nvkm_msec(device, 2000, | 199 | if (nvkm_msec(device, 2000, |
199 | if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x001e0000)) | 200 | if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x001e0000)) |
200 | break; | 201 | break; |
201 | ) < 0) { | 202 | ) < 0) { |
202 | nvkm_error(subdev, "ch %d fini timeout, %08x\n", chid, | 203 | nvkm_error(subdev, "ch %d fini timeout, %08x\n", user, |
203 | nvkm_rd32(device, 0x610200 + (chid * 0x10))); | 204 | nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); |
204 | } | 205 | } |
205 | 206 | ||
206 | /* disable error reporting and completion notifications */ | 207 | /* disable error reporting and completion notifications */ |
207 | nvkm_mask(device, 0x610028, 0x00010001 << chid, 0x00000000 << chid); | 208 | nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user); |
208 | } | 209 | } |
209 | 210 | ||
210 | static int | 211 | static int |
@@ -213,26 +214,27 @@ nv50_disp_dmac_init(struct nv50_disp_dmac *chan) | |||
213 | struct nv50_disp *disp = chan->base.root->disp; | 214 | struct nv50_disp *disp = chan->base.root->disp; |
214 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 215 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
215 | struct nvkm_device *device = subdev->device; | 216 | struct nvkm_device *device = subdev->device; |
216 | int chid = chan->base.chid; | 217 | int ctrl = chan->base.chid.ctrl; |
218 | int user = chan->base.chid.user; | ||
217 | 219 | ||
218 | /* enable error reporting */ | 220 | /* enable error reporting */ |
219 | nvkm_mask(device, 0x610028, 0x00010000 << chid, 0x00010000 << chid); | 221 | nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user); |
220 | 222 | ||
221 | /* initialise channel for dma command submission */ | 223 | /* initialise channel for dma command submission */ |
222 | nvkm_wr32(device, 0x610204 + (chid * 0x0010), chan->push); | 224 | nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push); |
223 | nvkm_wr32(device, 0x610208 + (chid * 0x0010), 0x00010000); | 225 | nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000); |
224 | nvkm_wr32(device, 0x61020c + (chid * 0x0010), chid); | 226 | nvkm_wr32(device, 0x61020c + (ctrl * 0x0010), ctrl); |
225 | nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010); | 227 | nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000010, 0x00000010); |
226 | nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000); | 228 | nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000); |
227 | nvkm_wr32(device, 0x610200 + (chid * 0x0010), 0x00000013); | 229 | nvkm_wr32(device, 0x610200 + (ctrl * 0x0010), 0x00000013); |
228 | 230 | ||
229 | /* wait for it to go inactive */ | 231 | /* wait for it to go inactive */ |
230 | if (nvkm_msec(device, 2000, | 232 | if (nvkm_msec(device, 2000, |
231 | if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x80000000)) | 233 | if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x80000000)) |
232 | break; | 234 | break; |
233 | ) < 0) { | 235 | ) < 0) { |
234 | nvkm_error(subdev, "ch %d init timeout, %08x\n", chid, | 236 | nvkm_error(subdev, "ch %d init timeout, %08x\n", user, |
235 | nvkm_rd32(device, 0x610200 + (chid * 0x10))); | 237 | nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); |
236 | return -EBUSY; | 238 | return -EBUSY; |
237 | } | 239 | } |
238 | 240 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h index 43ac05857853..ea4a0d062e31 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h | |||
@@ -30,7 +30,7 @@ int gf119_disp_dmac_bind(struct nv50_disp_dmac *, struct nvkm_object *, u32); | |||
30 | extern const struct nv50_disp_dmac_func gf119_disp_core_func; | 30 | extern const struct nv50_disp_dmac_func gf119_disp_core_func; |
31 | void gf119_disp_core_fini(struct nv50_disp_dmac *); | 31 | void gf119_disp_core_fini(struct nv50_disp_dmac *); |
32 | 32 | ||
33 | extern const struct nv50_disp_dmac_func gp104_disp_dmac_func; | 33 | extern const struct nv50_disp_dmac_func gp102_disp_dmac_func; |
34 | 34 | ||
35 | struct nv50_disp_dmac_oclass { | 35 | struct nv50_disp_dmac_oclass { |
36 | int (*ctor)(const struct nv50_disp_dmac_func *, | 36 | int (*ctor)(const struct nv50_disp_dmac_func *, |
@@ -95,7 +95,7 @@ extern const struct nv50_disp_dmac_oclass gm200_disp_core_oclass; | |||
95 | 95 | ||
96 | extern const struct nv50_disp_dmac_oclass gp100_disp_core_oclass; | 96 | extern const struct nv50_disp_dmac_oclass gp100_disp_core_oclass; |
97 | 97 | ||
98 | extern const struct nv50_disp_dmac_oclass gp104_disp_core_oclass; | 98 | extern const struct nv50_disp_dmac_oclass gp102_disp_core_oclass; |
99 | extern const struct nv50_disp_dmac_oclass gp104_disp_base_oclass; | 99 | extern const struct nv50_disp_dmac_oclass gp102_disp_base_oclass; |
100 | extern const struct nv50_disp_dmac_oclass gp104_disp_ovly_oclass; | 100 | extern const struct nv50_disp_dmac_oclass gp102_disp_ovly_oclass; |
101 | #endif | 101 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index 3bf3380336e4..f5d613f82709 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "rootnv50.h" | 25 | #include "rootnv50.h" |
26 | 26 | ||
27 | static void | 27 | static void |
28 | gp104_disp_intr_error(struct nv50_disp *disp, int chid) | 28 | gp102_disp_intr_error(struct nv50_disp *disp, int chid) |
29 | { | 29 | { |
30 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 30 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
31 | struct nvkm_device *device = subdev->device; | 31 | struct nvkm_device *device = subdev->device; |
@@ -51,12 +51,12 @@ gp104_disp_intr_error(struct nv50_disp *disp, int chid) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | static const struct nv50_disp_func | 53 | static const struct nv50_disp_func |
54 | gp104_disp = { | 54 | gp102_disp = { |
55 | .intr = gf119_disp_intr, | 55 | .intr = gf119_disp_intr, |
56 | .intr_error = gp104_disp_intr_error, | 56 | .intr_error = gp102_disp_intr_error, |
57 | .uevent = &gf119_disp_chan_uevent, | 57 | .uevent = &gf119_disp_chan_uevent, |
58 | .super = gf119_disp_intr_supervisor, | 58 | .super = gf119_disp_intr_supervisor, |
59 | .root = &gp104_disp_root_oclass, | 59 | .root = &gp102_disp_root_oclass, |
60 | .head.vblank_init = gf119_disp_vblank_init, | 60 | .head.vblank_init = gf119_disp_vblank_init, |
61 | .head.vblank_fini = gf119_disp_vblank_fini, | 61 | .head.vblank_fini = gf119_disp_vblank_fini, |
62 | .head.scanoutpos = gf119_disp_root_scanoutpos, | 62 | .head.scanoutpos = gf119_disp_root_scanoutpos, |
@@ -75,7 +75,7 @@ gp104_disp = { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | int | 77 | int |
78 | gp104_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) | 78 | gp102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) |
79 | { | 79 | { |
80 | return gf119_disp_new_(&gp104_disp, device, index, pdisp); | 80 | return gf119_disp_new_(&gp102_disp, device, index, pdisp); |
81 | } | 81 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c index 54a4ae8d66c6..5ad5d0f5db05 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c | |||
@@ -33,5 +33,5 @@ g84_disp_oimm_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_oimm_new, | 34 | .ctor = nv50_disp_oimm_new, |
35 | .func = &nv50_disp_pioc_func, | 35 | .func = &nv50_disp_pioc_func, |
36 | .chid = 5, | 36 | .chid = { 5, 5 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c index c658db54afc5..1f9fd3403f07 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c | |||
@@ -33,5 +33,5 @@ gf119_disp_oimm_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_oimm_new, | 34 | .ctor = nv50_disp_oimm_new, |
35 | .func = &gf119_disp_pioc_func, | 35 | .func = &gf119_disp_pioc_func, |
36 | .chid = 9, | 36 | .chid = { 9, 9 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c index b1fde8c125d6..0c09fe85e952 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c | |||
@@ -33,5 +33,5 @@ gk104_disp_oimm_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_oimm_new, | 34 | .ctor = nv50_disp_oimm_new, |
35 | .func = &gf119_disp_pioc_func, | 35 | .func = &gf119_disp_pioc_func, |
36 | .chid = 9, | 36 | .chid = { 9, 9 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c new file mode 100644 index 000000000000..abf82365c671 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright 2016 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 "channv50.h" | ||
25 | #include "rootnv50.h" | ||
26 | |||
27 | #include <nvif/class.h> | ||
28 | |||
29 | const struct nv50_disp_pioc_oclass | ||
30 | gp102_disp_oimm_oclass = { | ||
31 | .base.oclass = GK104_DISP_OVERLAY, | ||
32 | .base.minver = 0, | ||
33 | .base.maxver = 0, | ||
34 | .ctor = nv50_disp_oimm_new, | ||
35 | .func = &gf119_disp_pioc_func, | ||
36 | .chid = { 9, 13 }, | ||
37 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c index f4e7eb3d1177..1281db28aebd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c | |||
@@ -33,5 +33,5 @@ gt215_disp_oimm_oclass = { | |||
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_oimm_new, | 34 | .ctor = nv50_disp_oimm_new, |
35 | .func = &nv50_disp_pioc_func, | 35 | .func = &nv50_disp_pioc_func, |
36 | .chid = 5, | 36 | .chid = { 5, 5 }, |
37 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c index 3940b9c966ec..07540f3d32dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c | |||
@@ -33,7 +33,7 @@ | |||
33 | int | 33 | int |
34 | nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, | 34 | nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, |
35 | const struct nv50_disp_chan_mthd *mthd, | 35 | const struct nv50_disp_chan_mthd *mthd, |
36 | struct nv50_disp_root *root, int chid, | 36 | struct nv50_disp_root *root, int ctrl, int user, |
37 | const struct nvkm_oclass *oclass, void *data, u32 size, | 37 | const struct nvkm_oclass *oclass, void *data, u32 size, |
38 | struct nvkm_object **pobject) | 38 | struct nvkm_object **pobject) |
39 | { | 39 | { |
@@ -54,7 +54,7 @@ nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, | |||
54 | } else | 54 | } else |
55 | return ret; | 55 | return ret; |
56 | 56 | ||
57 | return nv50_disp_chan_new_(func, mthd, root, chid + head, | 57 | return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head, |
58 | head, oclass, pobject); | 58 | head, oclass, pobject); |
59 | } | 59 | } |
60 | 60 | ||
@@ -65,5 +65,5 @@ nv50_disp_oimm_oclass = { | |||
65 | .base.maxver = 0, | 65 | .base.maxver = 0, |
66 | .ctor = nv50_disp_oimm_new, | 66 | .ctor = nv50_disp_oimm_new, |
67 | .func = &nv50_disp_pioc_func, | 67 | .func = &nv50_disp_pioc_func, |
68 | .chid = 5, | 68 | .chid = { 5, 5 }, |
69 | }; | 69 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c index 97e2dd2d908e..589bd2f12b41 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c | |||
@@ -27,12 +27,12 @@ | |||
27 | #include <nvif/class.h> | 27 | #include <nvif/class.h> |
28 | 28 | ||
29 | const struct nv50_disp_dmac_oclass | 29 | const struct nv50_disp_dmac_oclass |
30 | gp104_disp_ovly_oclass = { | 30 | gp102_disp_ovly_oclass = { |
31 | .base.oclass = GK104_DISP_OVERLAY_CONTROL_DMA, | 31 | .base.oclass = GK104_DISP_OVERLAY_CONTROL_DMA, |
32 | .base.minver = 0, | 32 | .base.minver = 0, |
33 | .base.maxver = 0, | 33 | .base.maxver = 0, |
34 | .ctor = nv50_disp_ovly_new, | 34 | .ctor = nv50_disp_ovly_new, |
35 | .func = &gp104_disp_dmac_func, | 35 | .func = &gp102_disp_dmac_func, |
36 | .mthd = &gk104_disp_ovly_chan_mthd, | 36 | .mthd = &gk104_disp_ovly_chan_mthd, |
37 | .chid = 5, | 37 | .chid = 5, |
38 | }; | 38 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c index a625a9876e34..0abaa6431943 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c | |||
@@ -32,20 +32,21 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan) | |||
32 | struct nv50_disp *disp = chan->root->disp; | 32 | struct nv50_disp *disp = chan->root->disp; |
33 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 33 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
34 | struct nvkm_device *device = subdev->device; | 34 | struct nvkm_device *device = subdev->device; |
35 | int chid = chan->chid; | 35 | int ctrl = chan->chid.ctrl; |
36 | int user = chan->chid.user; | ||
36 | 37 | ||
37 | nvkm_mask(device, 0x610490 + (chid * 0x10), 0x00000001, 0x00000000); | 38 | nvkm_mask(device, 0x610490 + (ctrl * 0x10), 0x00000001, 0x00000000); |
38 | if (nvkm_msec(device, 2000, | 39 | if (nvkm_msec(device, 2000, |
39 | if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x00030000)) | 40 | if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x00030000)) |
40 | break; | 41 | break; |
41 | ) < 0) { | 42 | ) < 0) { |
42 | nvkm_error(subdev, "ch %d fini: %08x\n", chid, | 43 | nvkm_error(subdev, "ch %d fini: %08x\n", user, |
43 | nvkm_rd32(device, 0x610490 + (chid * 0x10))); | 44 | nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); |
44 | } | 45 | } |
45 | 46 | ||
46 | /* disable error reporting and completion notification */ | 47 | /* disable error reporting and completion notification */ |
47 | nvkm_mask(device, 0x610090, 0x00000001 << chid, 0x00000000); | 48 | nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000); |
48 | nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000000); | 49 | nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000); |
49 | } | 50 | } |
50 | 51 | ||
51 | static int | 52 | static int |
@@ -54,20 +55,21 @@ gf119_disp_pioc_init(struct nv50_disp_chan *chan) | |||
54 | struct nv50_disp *disp = chan->root->disp; | 55 | struct nv50_disp *disp = chan->root->disp; |
55 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 56 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
56 | struct nvkm_device *device = subdev->device; | 57 | struct nvkm_device *device = subdev->device; |
57 | int chid = chan->chid; | 58 | int ctrl = chan->chid.ctrl; |
59 | int user = chan->chid.user; | ||
58 | 60 | ||
59 | /* enable error reporting */ | 61 | /* enable error reporting */ |
60 | nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid); | 62 | nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); |
61 | 63 | ||
62 | /* activate channel */ | 64 | /* activate channel */ |
63 | nvkm_wr32(device, 0x610490 + (chid * 0x10), 0x00000001); | 65 | nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001); |
64 | if (nvkm_msec(device, 2000, | 66 | if (nvkm_msec(device, 2000, |
65 | u32 tmp = nvkm_rd32(device, 0x610490 + (chid * 0x10)); | 67 | u32 tmp = nvkm_rd32(device, 0x610490 + (ctrl * 0x10)); |
66 | if ((tmp & 0x00030000) == 0x00010000) | 68 | if ((tmp & 0x00030000) == 0x00010000) |
67 | break; | 69 | break; |
68 | ) < 0) { | 70 | ) < 0) { |
69 | nvkm_error(subdev, "ch %d init: %08x\n", chid, | 71 | nvkm_error(subdev, "ch %d init: %08x\n", user, |
70 | nvkm_rd32(device, 0x610490 + (chid * 0x10))); | 72 | nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); |
71 | return -EBUSY; | 73 | return -EBUSY; |
72 | } | 74 | } |
73 | 75 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c index 9d2618dacf20..0211e0e8a35f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c | |||
@@ -32,15 +32,16 @@ nv50_disp_pioc_fini(struct nv50_disp_chan *chan) | |||
32 | struct nv50_disp *disp = chan->root->disp; | 32 | struct nv50_disp *disp = chan->root->disp; |
33 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 33 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
34 | struct nvkm_device *device = subdev->device; | 34 | struct nvkm_device *device = subdev->device; |
35 | int chid = chan->chid; | 35 | int ctrl = chan->chid.ctrl; |
36 | int user = chan->chid.user; | ||
36 | 37 | ||
37 | nvkm_mask(device, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000); | 38 | nvkm_mask(device, 0x610200 + (ctrl * 0x10), 0x00000001, 0x00000000); |
38 | if (nvkm_msec(device, 2000, | 39 | if (nvkm_msec(device, 2000, |
39 | if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x00030000)) | 40 | if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000)) |
40 | break; | 41 | break; |
41 | ) < 0) { | 42 | ) < 0) { |
42 | nvkm_error(subdev, "ch %d timeout: %08x\n", chid, | 43 | nvkm_error(subdev, "ch %d timeout: %08x\n", user, |
43 | nvkm_rd32(device, 0x610200 + (chid * 0x10))); | 44 | nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); |
44 | } | 45 | } |
45 | } | 46 | } |
46 | 47 | ||
@@ -50,26 +51,27 @@ nv50_disp_pioc_init(struct nv50_disp_chan *chan) | |||
50 | struct nv50_disp *disp = chan->root->disp; | 51 | struct nv50_disp *disp = chan->root->disp; |
51 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; | 52 | struct nvkm_subdev *subdev = &disp->base.engine.subdev; |
52 | struct nvkm_device *device = subdev->device; | 53 | struct nvkm_device *device = subdev->device; |
53 | int chid = chan->chid; | 54 | int ctrl = chan->chid.ctrl; |
55 | int user = chan->chid.user; | ||
54 | 56 | ||
55 | nvkm_wr32(device, 0x610200 + (chid * 0x10), 0x00002000); | 57 | nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00002000); |
56 | if (nvkm_msec(device, 2000, | 58 | if (nvkm_msec(device, 2000, |
57 | if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x00030000)) | 59 | if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000)) |
58 | break; | 60 | break; |
59 | ) < 0) { | 61 | ) < 0) { |
60 | nvkm_error(subdev, "ch %d timeout0: %08x\n", chid, | 62 | nvkm_error(subdev, "ch %d timeout0: %08x\n", user, |
61 | nvkm_rd32(device, 0x610200 + (chid * 0x10))); | 63 | nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); |
62 | return -EBUSY; | 64 | return -EBUSY; |
63 | } | 65 | } |
64 | 66 | ||
65 | nvkm_wr32(device, 0x610200 + (chid * 0x10), 0x00000001); | 67 | nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00000001); |
66 | if (nvkm_msec(device, 2000, | 68 | if (nvkm_msec(device, 2000, |
67 | u32 tmp = nvkm_rd32(device, 0x610200 + (chid * 0x10)); | 69 | u32 tmp = nvkm_rd32(device, 0x610200 + (ctrl * 0x10)); |
68 | if ((tmp & 0x00030000) == 0x00010000) | 70 | if ((tmp & 0x00030000) == 0x00010000) |
69 | break; | 71 | break; |
70 | ) < 0) { | 72 | ) < 0) { |
71 | nvkm_error(subdev, "ch %d timeout1: %08x\n", chid, | 73 | nvkm_error(subdev, "ch %d timeout1: %08x\n", user, |
72 | nvkm_rd32(device, 0x610200 + (chid * 0x10))); | 74 | nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); |
73 | return -EBUSY; | 75 | return -EBUSY; |
74 | } | 76 | } |
75 | 77 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index 8443e04dc626..37122ca579ad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c | |||
@@ -27,32 +27,32 @@ | |||
27 | #include <nvif/class.h> | 27 | #include <nvif/class.h> |
28 | 28 | ||
29 | static const struct nv50_disp_root_func | 29 | static const struct nv50_disp_root_func |
30 | gp104_disp_root = { | 30 | gp102_disp_root = { |
31 | .init = gf119_disp_root_init, | 31 | .init = gf119_disp_root_init, |
32 | .fini = gf119_disp_root_fini, | 32 | .fini = gf119_disp_root_fini, |
33 | .dmac = { | 33 | .dmac = { |
34 | &gp104_disp_core_oclass, | 34 | &gp102_disp_core_oclass, |
35 | &gp104_disp_base_oclass, | 35 | &gp102_disp_base_oclass, |
36 | &gp104_disp_ovly_oclass, | 36 | &gp102_disp_ovly_oclass, |
37 | }, | 37 | }, |
38 | .pioc = { | 38 | .pioc = { |
39 | &gk104_disp_oimm_oclass, | 39 | &gp102_disp_oimm_oclass, |
40 | &gk104_disp_curs_oclass, | 40 | &gp102_disp_curs_oclass, |
41 | }, | 41 | }, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static int | 44 | static int |
45 | gp104_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass, | 45 | gp102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass, |
46 | void *data, u32 size, struct nvkm_object **pobject) | 46 | void *data, u32 size, struct nvkm_object **pobject) |
47 | { | 47 | { |
48 | return nv50_disp_root_new_(&gp104_disp_root, disp, oclass, | 48 | return nv50_disp_root_new_(&gp102_disp_root, disp, oclass, |
49 | data, size, pobject); | 49 | data, size, pobject); |
50 | } | 50 | } |
51 | 51 | ||
52 | const struct nvkm_disp_oclass | 52 | const struct nvkm_disp_oclass |
53 | gp104_disp_root_oclass = { | 53 | gp102_disp_root_oclass = { |
54 | .base.oclass = GP104_DISP, | 54 | .base.oclass = GP102_DISP, |
55 | .base.minver = -1, | 55 | .base.minver = -1, |
56 | .base.maxver = -1, | 56 | .base.maxver = -1, |
57 | .ctor = gp104_disp_root_new, | 57 | .ctor = gp102_disp_root_new, |
58 | }; | 58 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index c1158b22a721..e70dc6a9ff7d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c | |||
@@ -250,8 +250,8 @@ nv50_disp_root_pioc_new_(const struct nvkm_oclass *oclass, | |||
250 | { | 250 | { |
251 | const struct nv50_disp_pioc_oclass *sclass = oclass->priv; | 251 | const struct nv50_disp_pioc_oclass *sclass = oclass->priv; |
252 | struct nv50_disp_root *root = nv50_disp_root(oclass->parent); | 252 | struct nv50_disp_root *root = nv50_disp_root(oclass->parent); |
253 | return sclass->ctor(sclass->func, sclass->mthd, root, sclass->chid, | 253 | return sclass->ctor(sclass->func, sclass->mthd, root, sclass->chid.ctrl, |
254 | oclass, data, size, pobject); | 254 | sclass->chid.user, oclass, data, size, pobject); |
255 | } | 255 | } |
256 | 256 | ||
257 | static int | 257 | static int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index ad00f1724b72..b147cf5b3518 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h | |||
@@ -41,5 +41,5 @@ extern const struct nvkm_disp_oclass gk110_disp_root_oclass; | |||
41 | extern const struct nvkm_disp_oclass gm107_disp_root_oclass; | 41 | extern const struct nvkm_disp_oclass gm107_disp_root_oclass; |
42 | extern const struct nvkm_disp_oclass gm200_disp_root_oclass; | 42 | extern const struct nvkm_disp_oclass gm200_disp_root_oclass; |
43 | extern const struct nvkm_disp_oclass gp100_disp_root_oclass; | 43 | extern const struct nvkm_disp_oclass gp100_disp_root_oclass; |
44 | extern const struct nvkm_disp_oclass gp104_disp_root_oclass; | 44 | extern const struct nvkm_disp_oclass gp102_disp_root_oclass; |
45 | #endif | 45 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c index a410c0db8a08..42d94731655a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <subdev/bios.h> | 26 | #include <subdev/bios.h> |
27 | #include <subdev/bios/bit.h> | 27 | #include <subdev/bios/bit.h> |
28 | #include <subdev/bios/pmu.h> | 28 | #include <subdev/bios/pmu.h> |
29 | #include <subdev/timer.h> | ||
29 | 30 | ||
30 | static void | 31 | static void |
31 | pmu_code(struct nv50_devinit *init, u32 pmu, u32 img, u32 len, bool sec) | 32 | pmu_code(struct nv50_devinit *init, u32 pmu, u32 img, u32 len, bool sec) |
@@ -123,15 +124,6 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post) | |||
123 | return -EINVAL; | 124 | return -EINVAL; |
124 | } | 125 | } |
125 | 126 | ||
126 | /* reset PMU and load init table parser ucode */ | ||
127 | if (post) { | ||
128 | nvkm_mask(device, 0x000200, 0x00002000, 0x00000000); | ||
129 | nvkm_mask(device, 0x000200, 0x00002000, 0x00002000); | ||
130 | nvkm_rd32(device, 0x000200); | ||
131 | while (nvkm_rd32(device, 0x10a10c) & 0x00000006) { | ||
132 | } | ||
133 | } | ||
134 | |||
135 | ret = pmu_load(init, 0x04, post, &exec, &args); | 127 | ret = pmu_load(init, 0x04, post, &exec, &args); |
136 | if (ret) | 128 | if (ret) |
137 | return ret; | 129 | return ret; |
@@ -156,8 +148,11 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post) | |||
156 | if (post) { | 148 | if (post) { |
157 | nvkm_wr32(device, 0x10a040, 0x00005000); | 149 | nvkm_wr32(device, 0x10a040, 0x00005000); |
158 | pmu_exec(init, exec); | 150 | pmu_exec(init, exec); |
159 | while (!(nvkm_rd32(device, 0x10a040) & 0x00002000)) { | 151 | if (nvkm_msec(device, 2000, |
160 | } | 152 | if (nvkm_rd32(device, 0x10a040) & 0x00002000) |
153 | break; | ||
154 | ) < 0) | ||
155 | return -ETIMEDOUT; | ||
161 | } | 156 | } |
162 | 157 | ||
163 | /* load and execute some other ucode image (bios therm?) */ | 158 | /* load and execute some other ucode image (bios therm?) */ |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index ef47d57fcb87..63566ba12fbb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | |||
@@ -26,7 +26,7 @@ nvkm-y += nvkm/subdev/fb/gm107.o | |||
26 | nvkm-y += nvkm/subdev/fb/gm200.o | 26 | nvkm-y += nvkm/subdev/fb/gm200.o |
27 | nvkm-y += nvkm/subdev/fb/gm20b.o | 27 | nvkm-y += nvkm/subdev/fb/gm20b.o |
28 | nvkm-y += nvkm/subdev/fb/gp100.o | 28 | nvkm-y += nvkm/subdev/fb/gp100.o |
29 | nvkm-y += nvkm/subdev/fb/gp104.o | 29 | nvkm-y += nvkm/subdev/fb/gp102.o |
30 | 30 | ||
31 | nvkm-y += nvkm/subdev/fb/ram.o | 31 | nvkm-y += nvkm/subdev/fb/ram.o |
32 | nvkm-y += nvkm/subdev/fb/ramnv04.o | 32 | nvkm-y += nvkm/subdev/fb/ramnv04.o |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c index 92cb71861bec..73b4ae1c73dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <core/memory.h> | 27 | #include <core/memory.h> |
28 | 28 | ||
29 | static const struct nvkm_fb_func | 29 | static const struct nvkm_fb_func |
30 | gp104_fb = { | 30 | gp102_fb = { |
31 | .dtor = gf100_fb_dtor, | 31 | .dtor = gf100_fb_dtor, |
32 | .oneinit = gf100_fb_oneinit, | 32 | .oneinit = gf100_fb_oneinit, |
33 | .init = gp100_fb_init, | 33 | .init = gp100_fb_init, |
@@ -37,7 +37,7 @@ gp104_fb = { | |||
37 | }; | 37 | }; |
38 | 38 | ||
39 | int | 39 | int |
40 | gp104_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) | 40 | gp102_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) |
41 | { | 41 | { |
42 | return gf100_fb_new_(&gp104_fb, device, index, pfb); | 42 | return gf100_fb_new_(&gp102_fb, device, index, pfb); |
43 | } | 43 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild index 88b643b8664e..51fb4bf94a44 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild | |||
@@ -8,3 +8,5 @@ nvkm-y += nvkm/subdev/pmu/gk110.o | |||
8 | nvkm-y += nvkm/subdev/pmu/gk208.o | 8 | nvkm-y += nvkm/subdev/pmu/gk208.o |
9 | nvkm-y += nvkm/subdev/pmu/gk20a.o | 9 | nvkm-y += nvkm/subdev/pmu/gk20a.o |
10 | nvkm-y += nvkm/subdev/pmu/gm107.o | 10 | nvkm-y += nvkm/subdev/pmu/gm107.o |
11 | nvkm-y += nvkm/subdev/pmu/gp100.o | ||
12 | nvkm-y += nvkm/subdev/pmu/gp102.o | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c index 8dd164d13043..e611ce80f8ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c | |||
@@ -32,225 +32,85 @@ nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable) | |||
32 | pmu->func->pgob(pmu, enable); | 32 | pmu->func->pgob(pmu, enable); |
33 | } | 33 | } |
34 | 34 | ||
35 | int | ||
36 | nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2], | ||
37 | u32 process, u32 message, u32 data0, u32 data1) | ||
38 | { | ||
39 | struct nvkm_subdev *subdev = &pmu->subdev; | ||
40 | struct nvkm_device *device = subdev->device; | ||
41 | u32 addr; | ||
42 | |||
43 | mutex_lock(&subdev->mutex); | ||
44 | /* wait for a free slot in the fifo */ | ||
45 | addr = nvkm_rd32(device, 0x10a4a0); | ||
46 | if (nvkm_msec(device, 2000, | ||
47 | u32 tmp = nvkm_rd32(device, 0x10a4b0); | ||
48 | if (tmp != (addr ^ 8)) | ||
49 | break; | ||
50 | ) < 0) { | ||
51 | mutex_unlock(&subdev->mutex); | ||
52 | return -EBUSY; | ||
53 | } | ||
54 | |||
55 | /* we currently only support a single process at a time waiting | ||
56 | * on a synchronous reply, take the PMU mutex and tell the | ||
57 | * receive handler what we're waiting for | ||
58 | */ | ||
59 | if (reply) { | ||
60 | pmu->recv.message = message; | ||
61 | pmu->recv.process = process; | ||
62 | } | ||
63 | |||
64 | /* acquire data segment access */ | ||
65 | do { | ||
66 | nvkm_wr32(device, 0x10a580, 0x00000001); | ||
67 | } while (nvkm_rd32(device, 0x10a580) != 0x00000001); | ||
68 | |||
69 | /* write the packet */ | ||
70 | nvkm_wr32(device, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) + | ||
71 | pmu->send.base)); | ||
72 | nvkm_wr32(device, 0x10a1c4, process); | ||
73 | nvkm_wr32(device, 0x10a1c4, message); | ||
74 | nvkm_wr32(device, 0x10a1c4, data0); | ||
75 | nvkm_wr32(device, 0x10a1c4, data1); | ||
76 | nvkm_wr32(device, 0x10a4a0, (addr + 1) & 0x0f); | ||
77 | |||
78 | /* release data segment access */ | ||
79 | nvkm_wr32(device, 0x10a580, 0x00000000); | ||
80 | |||
81 | /* wait for reply, if requested */ | ||
82 | if (reply) { | ||
83 | wait_event(pmu->recv.wait, (pmu->recv.process == 0)); | ||
84 | reply[0] = pmu->recv.data[0]; | ||
85 | reply[1] = pmu->recv.data[1]; | ||
86 | } | ||
87 | |||
88 | mutex_unlock(&subdev->mutex); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static void | 35 | static void |
93 | nvkm_pmu_recv(struct work_struct *work) | 36 | nvkm_pmu_recv(struct work_struct *work) |
94 | { | 37 | { |
95 | struct nvkm_pmu *pmu = container_of(work, struct nvkm_pmu, recv.work); | 38 | struct nvkm_pmu *pmu = container_of(work, typeof(*pmu), recv.work); |
96 | struct nvkm_subdev *subdev = &pmu->subdev; | 39 | return pmu->func->recv(pmu); |
97 | struct nvkm_device *device = subdev->device; | 40 | } |
98 | u32 process, message, data0, data1; | ||
99 | |||
100 | /* nothing to do if GET == PUT */ | ||
101 | u32 addr = nvkm_rd32(device, 0x10a4cc); | ||
102 | if (addr == nvkm_rd32(device, 0x10a4c8)) | ||
103 | return; | ||
104 | |||
105 | /* acquire data segment access */ | ||
106 | do { | ||
107 | nvkm_wr32(device, 0x10a580, 0x00000002); | ||
108 | } while (nvkm_rd32(device, 0x10a580) != 0x00000002); | ||
109 | |||
110 | /* read the packet */ | ||
111 | nvkm_wr32(device, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) + | ||
112 | pmu->recv.base)); | ||
113 | process = nvkm_rd32(device, 0x10a1c4); | ||
114 | message = nvkm_rd32(device, 0x10a1c4); | ||
115 | data0 = nvkm_rd32(device, 0x10a1c4); | ||
116 | data1 = nvkm_rd32(device, 0x10a1c4); | ||
117 | nvkm_wr32(device, 0x10a4cc, (addr + 1) & 0x0f); | ||
118 | |||
119 | /* release data segment access */ | ||
120 | nvkm_wr32(device, 0x10a580, 0x00000000); | ||
121 | |||
122 | /* wake process if it's waiting on a synchronous reply */ | ||
123 | if (pmu->recv.process) { | ||
124 | if (process == pmu->recv.process && | ||
125 | message == pmu->recv.message) { | ||
126 | pmu->recv.data[0] = data0; | ||
127 | pmu->recv.data[1] = data1; | ||
128 | pmu->recv.process = 0; | ||
129 | wake_up(&pmu->recv.wait); | ||
130 | return; | ||
131 | } | ||
132 | } | ||
133 | 41 | ||
134 | /* right now there's no other expected responses from the engine, | 42 | int |
135 | * so assume that any unexpected message is an error. | 43 | nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2], |
136 | */ | 44 | u32 process, u32 message, u32 data0, u32 data1) |
137 | nvkm_warn(subdev, "%c%c%c%c %08x %08x %08x %08x\n", | 45 | { |
138 | (char)((process & 0x000000ff) >> 0), | 46 | if (!pmu || !pmu->func->send) |
139 | (char)((process & 0x0000ff00) >> 8), | 47 | return -ENODEV; |
140 | (char)((process & 0x00ff0000) >> 16), | 48 | return pmu->func->send(pmu, reply, process, message, data0, data1); |
141 | (char)((process & 0xff000000) >> 24), | ||
142 | process, message, data0, data1); | ||
143 | } | 49 | } |
144 | 50 | ||
145 | static void | 51 | static void |
146 | nvkm_pmu_intr(struct nvkm_subdev *subdev) | 52 | nvkm_pmu_intr(struct nvkm_subdev *subdev) |
147 | { | 53 | { |
148 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); | 54 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); |
149 | struct nvkm_device *device = pmu->subdev.device; | 55 | if (!pmu->func->intr) |
150 | u32 disp = nvkm_rd32(device, 0x10a01c); | 56 | return; |
151 | u32 intr = nvkm_rd32(device, 0x10a008) & disp & ~(disp >> 16); | 57 | pmu->func->intr(pmu); |
152 | |||
153 | if (intr & 0x00000020) { | ||
154 | u32 stat = nvkm_rd32(device, 0x10a16c); | ||
155 | if (stat & 0x80000000) { | ||
156 | nvkm_error(subdev, "UAS fault at %06x addr %08x\n", | ||
157 | stat & 0x00ffffff, | ||
158 | nvkm_rd32(device, 0x10a168)); | ||
159 | nvkm_wr32(device, 0x10a16c, 0x00000000); | ||
160 | intr &= ~0x00000020; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | if (intr & 0x00000040) { | ||
165 | schedule_work(&pmu->recv.work); | ||
166 | nvkm_wr32(device, 0x10a004, 0x00000040); | ||
167 | intr &= ~0x00000040; | ||
168 | } | ||
169 | |||
170 | if (intr & 0x00000080) { | ||
171 | nvkm_info(subdev, "wr32 %06x %08x\n", | ||
172 | nvkm_rd32(device, 0x10a7a0), | ||
173 | nvkm_rd32(device, 0x10a7a4)); | ||
174 | nvkm_wr32(device, 0x10a004, 0x00000080); | ||
175 | intr &= ~0x00000080; | ||
176 | } | ||
177 | |||
178 | if (intr) { | ||
179 | nvkm_error(subdev, "intr %08x\n", intr); | ||
180 | nvkm_wr32(device, 0x10a004, intr); | ||
181 | } | ||
182 | } | 58 | } |
183 | 59 | ||
184 | static int | 60 | static int |
185 | nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend) | 61 | nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend) |
186 | { | 62 | { |
187 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); | 63 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); |
188 | struct nvkm_device *device = pmu->subdev.device; | ||
189 | 64 | ||
190 | nvkm_wr32(device, 0x10a014, 0x00000060); | 65 | if (pmu->func->fini) |
66 | pmu->func->fini(pmu); | ||
67 | |||
191 | flush_work(&pmu->recv.work); | 68 | flush_work(&pmu->recv.work); |
192 | return 0; | 69 | return 0; |
193 | } | 70 | } |
194 | 71 | ||
195 | static int | 72 | static int |
196 | nvkm_pmu_init(struct nvkm_subdev *subdev) | 73 | nvkm_pmu_reset(struct nvkm_pmu *pmu) |
197 | { | 74 | { |
198 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); | ||
199 | struct nvkm_device *device = pmu->subdev.device; | 75 | struct nvkm_device *device = pmu->subdev.device; |
200 | int i; | ||
201 | 76 | ||
202 | /* prevent previous ucode from running, wait for idle, reset */ | 77 | if (!(nvkm_rd32(device, 0x000200) & 0x00002000)) |
203 | nvkm_wr32(device, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */ | 78 | return 0; |
79 | |||
80 | /* Inhibit interrupts, and wait for idle. */ | ||
81 | nvkm_wr32(device, 0x10a014, 0x0000ffff); | ||
204 | nvkm_msec(device, 2000, | 82 | nvkm_msec(device, 2000, |
205 | if (!nvkm_rd32(device, 0x10a04c)) | 83 | if (!nvkm_rd32(device, 0x10a04c)) |
206 | break; | 84 | break; |
207 | ); | 85 | ); |
208 | nvkm_mask(device, 0x000200, 0x00002000, 0x00000000); | 86 | |
209 | nvkm_mask(device, 0x000200, 0x00002000, 0x00002000); | 87 | /* Reset. */ |
210 | nvkm_rd32(device, 0x000200); | 88 | pmu->func->reset(pmu); |
89 | |||
90 | /* Wait for IMEM/DMEM scrubbing to be complete. */ | ||
211 | nvkm_msec(device, 2000, | 91 | nvkm_msec(device, 2000, |
212 | if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006)) | 92 | if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006)) |
213 | break; | 93 | break; |
214 | ); | 94 | ); |
215 | 95 | ||
216 | /* upload data segment */ | 96 | return 0; |
217 | nvkm_wr32(device, 0x10a1c0, 0x01000000); | 97 | } |
218 | for (i = 0; i < pmu->func->data.size / 4; i++) | ||
219 | nvkm_wr32(device, 0x10a1c4, pmu->func->data.data[i]); | ||
220 | |||
221 | /* upload code segment */ | ||
222 | nvkm_wr32(device, 0x10a180, 0x01000000); | ||
223 | for (i = 0; i < pmu->func->code.size / 4; i++) { | ||
224 | if ((i & 0x3f) == 0) | ||
225 | nvkm_wr32(device, 0x10a188, i >> 6); | ||
226 | nvkm_wr32(device, 0x10a184, pmu->func->code.data[i]); | ||
227 | } | ||
228 | |||
229 | /* start it running */ | ||
230 | nvkm_wr32(device, 0x10a10c, 0x00000000); | ||
231 | nvkm_wr32(device, 0x10a104, 0x00000000); | ||
232 | nvkm_wr32(device, 0x10a100, 0x00000002); | ||
233 | |||
234 | /* wait for valid host->pmu ring configuration */ | ||
235 | if (nvkm_msec(device, 2000, | ||
236 | if (nvkm_rd32(device, 0x10a4d0)) | ||
237 | break; | ||
238 | ) < 0) | ||
239 | return -EBUSY; | ||
240 | pmu->send.base = nvkm_rd32(device, 0x10a4d0) & 0x0000ffff; | ||
241 | pmu->send.size = nvkm_rd32(device, 0x10a4d0) >> 16; | ||
242 | 98 | ||
243 | /* wait for valid pmu->host ring configuration */ | 99 | static int |
244 | if (nvkm_msec(device, 2000, | 100 | nvkm_pmu_preinit(struct nvkm_subdev *subdev) |
245 | if (nvkm_rd32(device, 0x10a4dc)) | 101 | { |
246 | break; | 102 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); |
247 | ) < 0) | 103 | return nvkm_pmu_reset(pmu); |
248 | return -EBUSY; | 104 | } |
249 | pmu->recv.base = nvkm_rd32(device, 0x10a4dc) & 0x0000ffff; | ||
250 | pmu->recv.size = nvkm_rd32(device, 0x10a4dc) >> 16; | ||
251 | 105 | ||
252 | nvkm_wr32(device, 0x10a010, 0x000000e0); | 106 | static int |
253 | return 0; | 107 | nvkm_pmu_init(struct nvkm_subdev *subdev) |
108 | { | ||
109 | struct nvkm_pmu *pmu = nvkm_pmu(subdev); | ||
110 | int ret = nvkm_pmu_reset(pmu); | ||
111 | if (ret == 0 && pmu->func->init) | ||
112 | ret = pmu->func->init(pmu); | ||
113 | return ret; | ||
254 | } | 114 | } |
255 | 115 | ||
256 | static void * | 116 | static void * |
@@ -262,6 +122,7 @@ nvkm_pmu_dtor(struct nvkm_subdev *subdev) | |||
262 | static const struct nvkm_subdev_func | 122 | static const struct nvkm_subdev_func |
263 | nvkm_pmu = { | 123 | nvkm_pmu = { |
264 | .dtor = nvkm_pmu_dtor, | 124 | .dtor = nvkm_pmu_dtor, |
125 | .preinit = nvkm_pmu_preinit, | ||
265 | .init = nvkm_pmu_init, | 126 | .init = nvkm_pmu_init, |
266 | .fini = nvkm_pmu_fini, | 127 | .fini = nvkm_pmu_fini, |
267 | .intr = nvkm_pmu_intr, | 128 | .intr = nvkm_pmu_intr, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c index aeb8ccd891fc..0e36d4cb7201 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c | |||
@@ -30,6 +30,12 @@ gf100_pmu = { | |||
30 | .code.size = sizeof(gf100_pmu_code), | 30 | .code.size = sizeof(gf100_pmu_code), |
31 | .data.data = gf100_pmu_data, | 31 | .data.data = gf100_pmu_data, |
32 | .data.size = sizeof(gf100_pmu_data), | 32 | .data.size = sizeof(gf100_pmu_data), |
33 | .reset = gt215_pmu_reset, | ||
34 | .init = gt215_pmu_init, | ||
35 | .fini = gt215_pmu_fini, | ||
36 | .intr = gt215_pmu_intr, | ||
37 | .send = gt215_pmu_send, | ||
38 | .recv = gt215_pmu_recv, | ||
33 | }; | 39 | }; |
34 | 40 | ||
35 | int | 41 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c index fbc88d8ecd4d..0e4ba4248b15 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c | |||
@@ -30,6 +30,12 @@ gf119_pmu = { | |||
30 | .code.size = sizeof(gf119_pmu_code), | 30 | .code.size = sizeof(gf119_pmu_code), |
31 | .data.data = gf119_pmu_data, | 31 | .data.data = gf119_pmu_data, |
32 | .data.size = sizeof(gf119_pmu_data), | 32 | .data.size = sizeof(gf119_pmu_data), |
33 | .reset = gt215_pmu_reset, | ||
34 | .init = gt215_pmu_init, | ||
35 | .fini = gt215_pmu_fini, | ||
36 | .intr = gt215_pmu_intr, | ||
37 | .send = gt215_pmu_send, | ||
38 | .recv = gt215_pmu_recv, | ||
33 | }; | 39 | }; |
34 | 40 | ||
35 | int | 41 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c index 86f9f3b13f71..2ad858d825ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c | |||
@@ -109,6 +109,12 @@ gk104_pmu = { | |||
109 | .code.size = sizeof(gk104_pmu_code), | 109 | .code.size = sizeof(gk104_pmu_code), |
110 | .data.data = gk104_pmu_data, | 110 | .data.data = gk104_pmu_data, |
111 | .data.size = sizeof(gk104_pmu_data), | 111 | .data.size = sizeof(gk104_pmu_data), |
112 | .reset = gt215_pmu_reset, | ||
113 | .init = gt215_pmu_init, | ||
114 | .fini = gt215_pmu_fini, | ||
115 | .intr = gt215_pmu_intr, | ||
116 | .send = gt215_pmu_send, | ||
117 | .recv = gt215_pmu_recv, | ||
112 | .pgob = gk104_pmu_pgob, | 118 | .pgob = gk104_pmu_pgob, |
113 | }; | 119 | }; |
114 | 120 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c index ae255247c9d1..fc4b8ecfdaeb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c | |||
@@ -88,6 +88,12 @@ gk110_pmu = { | |||
88 | .code.size = sizeof(gk110_pmu_code), | 88 | .code.size = sizeof(gk110_pmu_code), |
89 | .data.data = gk110_pmu_data, | 89 | .data.data = gk110_pmu_data, |
90 | .data.size = sizeof(gk110_pmu_data), | 90 | .data.size = sizeof(gk110_pmu_data), |
91 | .reset = gt215_pmu_reset, | ||
92 | .init = gt215_pmu_init, | ||
93 | .fini = gt215_pmu_fini, | ||
94 | .intr = gt215_pmu_intr, | ||
95 | .send = gt215_pmu_send, | ||
96 | .recv = gt215_pmu_recv, | ||
91 | .pgob = gk110_pmu_pgob, | 97 | .pgob = gk110_pmu_pgob, |
92 | }; | 98 | }; |
93 | 99 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c index 3b4917637902..e9a91277683a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c | |||
@@ -30,6 +30,12 @@ gk208_pmu = { | |||
30 | .code.size = sizeof(gk208_pmu_code), | 30 | .code.size = sizeof(gk208_pmu_code), |
31 | .data.data = gk208_pmu_data, | 31 | .data.data = gk208_pmu_data, |
32 | .data.size = sizeof(gk208_pmu_data), | 32 | .data.size = sizeof(gk208_pmu_data), |
33 | .reset = gt215_pmu_reset, | ||
34 | .init = gt215_pmu_init, | ||
35 | .fini = gt215_pmu_fini, | ||
36 | .intr = gt215_pmu_intr, | ||
37 | .send = gt215_pmu_send, | ||
38 | .recv = gt215_pmu_recv, | ||
33 | .pgob = gk110_pmu_pgob, | 39 | .pgob = gk110_pmu_pgob, |
34 | }; | 40 | }; |
35 | 41 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c index 31b8692b4641..9a248ed75f09 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c | |||
@@ -32,6 +32,12 @@ gm107_pmu = { | |||
32 | .code.size = sizeof(gm107_pmu_code), | 32 | .code.size = sizeof(gm107_pmu_code), |
33 | .data.data = gm107_pmu_data, | 33 | .data.data = gm107_pmu_data, |
34 | .data.size = sizeof(gm107_pmu_data), | 34 | .data.size = sizeof(gm107_pmu_data), |
35 | .reset = gt215_pmu_reset, | ||
36 | .init = gt215_pmu_init, | ||
37 | .fini = gt215_pmu_fini, | ||
38 | .intr = gt215_pmu_intr, | ||
39 | .send = gt215_pmu_send, | ||
40 | .recv = gt215_pmu_recv, | ||
35 | }; | 41 | }; |
36 | 42 | ||
37 | int | 43 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c new file mode 100644 index 000000000000..6c41c20c85a7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright 2016 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 "priv.h" | ||
25 | |||
26 | static const struct nvkm_pmu_func | ||
27 | gp100_pmu = { | ||
28 | .reset = gt215_pmu_reset, | ||
29 | }; | ||
30 | |||
31 | int | ||
32 | gp100_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu) | ||
33 | { | ||
34 | return nvkm_pmu_new_(&gp100_pmu, device, index, ppmu); | ||
35 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c new file mode 100644 index 000000000000..f017352206c9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright 2016 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 "priv.h" | ||
25 | |||
26 | static void | ||
27 | gp102_pmu_reset(struct nvkm_pmu *pmu) | ||
28 | { | ||
29 | struct nvkm_device *device = pmu->subdev.device; | ||
30 | nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000001); | ||
31 | nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000); | ||
32 | } | ||
33 | |||
34 | static const struct nvkm_pmu_func | ||
35 | gp102_pmu = { | ||
36 | .reset = gp102_pmu_reset, | ||
37 | }; | ||
38 | |||
39 | int | ||
40 | gp102_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu) | ||
41 | { | ||
42 | return nvkm_pmu_new_(&gp102_pmu, device, index, ppmu); | ||
43 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c index dcf9eaf274aa..90d428b3be97 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c | |||
@@ -24,12 +24,229 @@ | |||
24 | #include "priv.h" | 24 | #include "priv.h" |
25 | #include "fuc/gt215.fuc3.h" | 25 | #include "fuc/gt215.fuc3.h" |
26 | 26 | ||
27 | #include <subdev/timer.h> | ||
28 | |||
29 | int | ||
30 | gt215_pmu_send(struct nvkm_pmu *pmu, u32 reply[2], | ||
31 | u32 process, u32 message, u32 data0, u32 data1) | ||
32 | { | ||
33 | struct nvkm_subdev *subdev = &pmu->subdev; | ||
34 | struct nvkm_device *device = subdev->device; | ||
35 | u32 addr; | ||
36 | |||
37 | mutex_lock(&subdev->mutex); | ||
38 | /* wait for a free slot in the fifo */ | ||
39 | addr = nvkm_rd32(device, 0x10a4a0); | ||
40 | if (nvkm_msec(device, 2000, | ||
41 | u32 tmp = nvkm_rd32(device, 0x10a4b0); | ||
42 | if (tmp != (addr ^ 8)) | ||
43 | break; | ||
44 | ) < 0) { | ||
45 | mutex_unlock(&subdev->mutex); | ||
46 | return -EBUSY; | ||
47 | } | ||
48 | |||
49 | /* we currently only support a single process at a time waiting | ||
50 | * on a synchronous reply, take the PMU mutex and tell the | ||
51 | * receive handler what we're waiting for | ||
52 | */ | ||
53 | if (reply) { | ||
54 | pmu->recv.message = message; | ||
55 | pmu->recv.process = process; | ||
56 | } | ||
57 | |||
58 | /* acquire data segment access */ | ||
59 | do { | ||
60 | nvkm_wr32(device, 0x10a580, 0x00000001); | ||
61 | } while (nvkm_rd32(device, 0x10a580) != 0x00000001); | ||
62 | |||
63 | /* write the packet */ | ||
64 | nvkm_wr32(device, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) + | ||
65 | pmu->send.base)); | ||
66 | nvkm_wr32(device, 0x10a1c4, process); | ||
67 | nvkm_wr32(device, 0x10a1c4, message); | ||
68 | nvkm_wr32(device, 0x10a1c4, data0); | ||
69 | nvkm_wr32(device, 0x10a1c4, data1); | ||
70 | nvkm_wr32(device, 0x10a4a0, (addr + 1) & 0x0f); | ||
71 | |||
72 | /* release data segment access */ | ||
73 | nvkm_wr32(device, 0x10a580, 0x00000000); | ||
74 | |||
75 | /* wait for reply, if requested */ | ||
76 | if (reply) { | ||
77 | wait_event(pmu->recv.wait, (pmu->recv.process == 0)); | ||
78 | reply[0] = pmu->recv.data[0]; | ||
79 | reply[1] = pmu->recv.data[1]; | ||
80 | } | ||
81 | |||
82 | mutex_unlock(&subdev->mutex); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | void | ||
87 | gt215_pmu_recv(struct nvkm_pmu *pmu) | ||
88 | { | ||
89 | struct nvkm_subdev *subdev = &pmu->subdev; | ||
90 | struct nvkm_device *device = subdev->device; | ||
91 | u32 process, message, data0, data1; | ||
92 | |||
93 | /* nothing to do if GET == PUT */ | ||
94 | u32 addr = nvkm_rd32(device, 0x10a4cc); | ||
95 | if (addr == nvkm_rd32(device, 0x10a4c8)) | ||
96 | return; | ||
97 | |||
98 | /* acquire data segment access */ | ||
99 | do { | ||
100 | nvkm_wr32(device, 0x10a580, 0x00000002); | ||
101 | } while (nvkm_rd32(device, 0x10a580) != 0x00000002); | ||
102 | |||
103 | /* read the packet */ | ||
104 | nvkm_wr32(device, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) + | ||
105 | pmu->recv.base)); | ||
106 | process = nvkm_rd32(device, 0x10a1c4); | ||
107 | message = nvkm_rd32(device, 0x10a1c4); | ||
108 | data0 = nvkm_rd32(device, 0x10a1c4); | ||
109 | data1 = nvkm_rd32(device, 0x10a1c4); | ||
110 | nvkm_wr32(device, 0x10a4cc, (addr + 1) & 0x0f); | ||
111 | |||
112 | /* release data segment access */ | ||
113 | nvkm_wr32(device, 0x10a580, 0x00000000); | ||
114 | |||
115 | /* wake process if it's waiting on a synchronous reply */ | ||
116 | if (pmu->recv.process) { | ||
117 | if (process == pmu->recv.process && | ||
118 | message == pmu->recv.message) { | ||
119 | pmu->recv.data[0] = data0; | ||
120 | pmu->recv.data[1] = data1; | ||
121 | pmu->recv.process = 0; | ||
122 | wake_up(&pmu->recv.wait); | ||
123 | return; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /* right now there's no other expected responses from the engine, | ||
128 | * so assume that any unexpected message is an error. | ||
129 | */ | ||
130 | nvkm_warn(subdev, "%c%c%c%c %08x %08x %08x %08x\n", | ||
131 | (char)((process & 0x000000ff) >> 0), | ||
132 | (char)((process & 0x0000ff00) >> 8), | ||
133 | (char)((process & 0x00ff0000) >> 16), | ||
134 | (char)((process & 0xff000000) >> 24), | ||
135 | process, message, data0, data1); | ||
136 | } | ||
137 | |||
138 | void | ||
139 | gt215_pmu_intr(struct nvkm_pmu *pmu) | ||
140 | { | ||
141 | struct nvkm_subdev *subdev = &pmu->subdev; | ||
142 | struct nvkm_device *device = subdev->device; | ||
143 | u32 disp = nvkm_rd32(device, 0x10a01c); | ||
144 | u32 intr = nvkm_rd32(device, 0x10a008) & disp & ~(disp >> 16); | ||
145 | |||
146 | if (intr & 0x00000020) { | ||
147 | u32 stat = nvkm_rd32(device, 0x10a16c); | ||
148 | if (stat & 0x80000000) { | ||
149 | nvkm_error(subdev, "UAS fault at %06x addr %08x\n", | ||
150 | stat & 0x00ffffff, | ||
151 | nvkm_rd32(device, 0x10a168)); | ||
152 | nvkm_wr32(device, 0x10a16c, 0x00000000); | ||
153 | intr &= ~0x00000020; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | if (intr & 0x00000040) { | ||
158 | schedule_work(&pmu->recv.work); | ||
159 | nvkm_wr32(device, 0x10a004, 0x00000040); | ||
160 | intr &= ~0x00000040; | ||
161 | } | ||
162 | |||
163 | if (intr & 0x00000080) { | ||
164 | nvkm_info(subdev, "wr32 %06x %08x\n", | ||
165 | nvkm_rd32(device, 0x10a7a0), | ||
166 | nvkm_rd32(device, 0x10a7a4)); | ||
167 | nvkm_wr32(device, 0x10a004, 0x00000080); | ||
168 | intr &= ~0x00000080; | ||
169 | } | ||
170 | |||
171 | if (intr) { | ||
172 | nvkm_error(subdev, "intr %08x\n", intr); | ||
173 | nvkm_wr32(device, 0x10a004, intr); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | void | ||
178 | gt215_pmu_fini(struct nvkm_pmu *pmu) | ||
179 | { | ||
180 | nvkm_wr32(pmu->subdev.device, 0x10a014, 0x00000060); | ||
181 | } | ||
182 | |||
183 | void | ||
184 | gt215_pmu_reset(struct nvkm_pmu *pmu) | ||
185 | { | ||
186 | struct nvkm_device *device = pmu->subdev.device; | ||
187 | nvkm_mask(device, 0x000200, 0x00002000, 0x00000000); | ||
188 | nvkm_mask(device, 0x000200, 0x00002000, 0x00002000); | ||
189 | nvkm_rd32(device, 0x000200); | ||
190 | } | ||
191 | |||
192 | int | ||
193 | gt215_pmu_init(struct nvkm_pmu *pmu) | ||
194 | { | ||
195 | struct nvkm_device *device = pmu->subdev.device; | ||
196 | int i; | ||
197 | |||
198 | /* upload data segment */ | ||
199 | nvkm_wr32(device, 0x10a1c0, 0x01000000); | ||
200 | for (i = 0; i < pmu->func->data.size / 4; i++) | ||
201 | nvkm_wr32(device, 0x10a1c4, pmu->func->data.data[i]); | ||
202 | |||
203 | /* upload code segment */ | ||
204 | nvkm_wr32(device, 0x10a180, 0x01000000); | ||
205 | for (i = 0; i < pmu->func->code.size / 4; i++) { | ||
206 | if ((i & 0x3f) == 0) | ||
207 | nvkm_wr32(device, 0x10a188, i >> 6); | ||
208 | nvkm_wr32(device, 0x10a184, pmu->func->code.data[i]); | ||
209 | } | ||
210 | |||
211 | /* start it running */ | ||
212 | nvkm_wr32(device, 0x10a10c, 0x00000000); | ||
213 | nvkm_wr32(device, 0x10a104, 0x00000000); | ||
214 | nvkm_wr32(device, 0x10a100, 0x00000002); | ||
215 | |||
216 | /* wait for valid host->pmu ring configuration */ | ||
217 | if (nvkm_msec(device, 2000, | ||
218 | if (nvkm_rd32(device, 0x10a4d0)) | ||
219 | break; | ||
220 | ) < 0) | ||
221 | return -EBUSY; | ||
222 | pmu->send.base = nvkm_rd32(device, 0x10a4d0) & 0x0000ffff; | ||
223 | pmu->send.size = nvkm_rd32(device, 0x10a4d0) >> 16; | ||
224 | |||
225 | /* wait for valid pmu->host ring configuration */ | ||
226 | if (nvkm_msec(device, 2000, | ||
227 | if (nvkm_rd32(device, 0x10a4dc)) | ||
228 | break; | ||
229 | ) < 0) | ||
230 | return -EBUSY; | ||
231 | pmu->recv.base = nvkm_rd32(device, 0x10a4dc) & 0x0000ffff; | ||
232 | pmu->recv.size = nvkm_rd32(device, 0x10a4dc) >> 16; | ||
233 | |||
234 | nvkm_wr32(device, 0x10a010, 0x000000e0); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
27 | static const struct nvkm_pmu_func | 238 | static const struct nvkm_pmu_func |
28 | gt215_pmu = { | 239 | gt215_pmu = { |
29 | .code.data = gt215_pmu_code, | 240 | .code.data = gt215_pmu_code, |
30 | .code.size = sizeof(gt215_pmu_code), | 241 | .code.size = sizeof(gt215_pmu_code), |
31 | .data.data = gt215_pmu_data, | 242 | .data.data = gt215_pmu_data, |
32 | .data.size = sizeof(gt215_pmu_data), | 243 | .data.size = sizeof(gt215_pmu_data), |
244 | .reset = gt215_pmu_reset, | ||
245 | .init = gt215_pmu_init, | ||
246 | .fini = gt215_pmu_fini, | ||
247 | .intr = gt215_pmu_intr, | ||
248 | .send = gt215_pmu_send, | ||
249 | .recv = gt215_pmu_recv, | ||
33 | }; | 250 | }; |
34 | 251 | ||
35 | int | 252 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h index 73b811ccc2d5..2e2179a4ad17 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h | |||
@@ -18,8 +18,22 @@ struct nvkm_pmu_func { | |||
18 | u32 size; | 18 | u32 size; |
19 | } data; | 19 | } data; |
20 | 20 | ||
21 | void (*reset)(struct nvkm_pmu *); | ||
22 | int (*init)(struct nvkm_pmu *); | ||
23 | void (*fini)(struct nvkm_pmu *); | ||
24 | void (*intr)(struct nvkm_pmu *); | ||
25 | int (*send)(struct nvkm_pmu *, u32 reply[2], u32 process, | ||
26 | u32 message, u32 data0, u32 data1); | ||
27 | void (*recv)(struct nvkm_pmu *); | ||
21 | void (*pgob)(struct nvkm_pmu *, bool); | 28 | void (*pgob)(struct nvkm_pmu *, bool); |
22 | }; | 29 | }; |
23 | 30 | ||
31 | void gt215_pmu_reset(struct nvkm_pmu *); | ||
32 | int gt215_pmu_init(struct nvkm_pmu *); | ||
33 | void gt215_pmu_fini(struct nvkm_pmu *); | ||
34 | void gt215_pmu_intr(struct nvkm_pmu *); | ||
35 | void gt215_pmu_recv(struct nvkm_pmu *); | ||
36 | int gt215_pmu_send(struct nvkm_pmu *, u32[2], u32, u32, u32, u32); | ||
37 | |||
24 | void gk110_pmu_pgob(struct nvkm_pmu *, bool); | 38 | void gk110_pmu_pgob(struct nvkm_pmu *, bool); |
25 | #endif | 39 | #endif |