From b62880f7966781eb0b3b1e50f63d6aac362476d3 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 23 Feb 2017 18:41:41 +0900 Subject: [PATCH] drm/nouveau/core: add SEC2 engine SEC2 is the name given by NVIDIA to the SEC engine post-Fermi (reasons unknown). Even though it shares the same address range as SEC, its usage is quite different and this justifies a new engine. Add this engine and make TOP use it all post-TOP devices should use this implementation and not the older SEC. Also quickly add the short gp102 implementation which will be used for falcon booting purposes. Signed-off-by: Alexandre Courbot Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/core/device.h | 3 + .../drm/nouveau/include/nvkm/engine/sec2.h | 13 +++ drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 2 + .../gpu/drm/nouveau/nvkm/engine/device/priv.h | 1 + .../gpu/drm/nouveau/nvkm/engine/sec2/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/engine/sec2/base.c | 101 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/sec2/gp102.c | 30 ++++++ .../gpu/drm/nouveau/nvkm/engine/sec2/priv.h | 9 ++ .../gpu/drm/nouveau/nvkm/subdev/top/gk104.c | 2 +- 11 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/sec2/Kbuild create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 6d6e7e71067b..bb4c214f1046 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -59,6 +59,7 @@ enum nvkm_devidx { NVKM_ENGINE_NVDEC, NVKM_ENGINE_PM, NVKM_ENGINE_SEC, + NVKM_ENGINE_SEC2, NVKM_ENGINE_SW, NVKM_ENGINE_VIC, NVKM_ENGINE_VP, @@ -158,6 +159,7 @@ struct nvkm_device { struct nvkm_nvdec *nvdec; struct nvkm_pm *pm; struct nvkm_engine *sec; + struct nvkm_sec2 *sec2; struct nvkm_sw *sw; struct nvkm_engine *vic; struct nvkm_engine *vp; @@ -228,6 +230,7 @@ struct nvkm_device_chip { int (*nvdec )(struct nvkm_device *, int idx, struct nvkm_nvdec **); int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **); int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*sec2 )(struct nvkm_device *, int idx, struct nvkm_sec2 **); int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **); int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h new file mode 100644 index 000000000000..d3db1b1e75c4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec2.h @@ -0,0 +1,13 @@ +#ifndef __NVKM_SEC2_H__ +#define __NVKM_SEC2_H__ +#include + +struct nvkm_sec2 { + struct nvkm_engine engine; + struct nvkm_falcon *falcon; + struct nvkm_msgqueue *queue; + struct work_struct work; +}; + +int gp102_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index 19044aba265e..a134d225f958 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -78,6 +78,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = { [NVKM_ENGINE_NVDEC ] = "nvdec", [NVKM_ENGINE_PM ] = "pm", [NVKM_ENGINE_SEC ] = "sec", + [NVKM_ENGINE_SEC2 ] = "sec2", [NVKM_ENGINE_SW ] = "sw", [NVKM_ENGINE_VIC ] = "vic", [NVKM_ENGINE_VP ] = "vp", diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild index c2c8d2ac01b8..78571e8b01c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild @@ -18,6 +18,7 @@ include $(src)/nvkm/engine/nvenc/Kbuild include $(src)/nvkm/engine/nvdec/Kbuild include $(src)/nvkm/engine/pm/Kbuild include $(src)/nvkm/engine/sec/Kbuild +include $(src)/nvkm/engine/sec2/Kbuild include $(src)/nvkm/engine/sw/Kbuild include $(src)/nvkm/engine/vic/Kbuild include $(src)/nvkm/engine/vp/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 883e6e474d1b..cf76d6c657ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2365,6 +2365,7 @@ nvkm_device_engine(struct nvkm_device *device, int index) _(NVDEC , device->nvdec , &device->nvdec->engine); _(PM , device->pm , &device->pm->engine); _(SEC , device->sec , device->sec); + _(SEC2 , device->sec2 , &device->sec2->engine); _(SW , device->sw , &device->sw->engine); _(VIC , device->vic , device->vic); _(VP , device->vp , device->vp); @@ -2812,6 +2813,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, _(NVKM_ENGINE_NVDEC , nvdec); _(NVKM_ENGINE_PM , pm); _(NVKM_ENGINE_SEC , sec); + _(NVKM_ENGINE_SEC2 , sec2); _(NVKM_ENGINE_SW , sw); _(NVKM_ENGINE_VIC , vic); _(NVKM_ENGINE_VP , vp); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index 1a06ac175f55..6c16f3835f44 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/Kbuild new file mode 100644 index 000000000000..4b17254cfbd0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/Kbuild @@ -0,0 +1,2 @@ +nvkm-y += nvkm/engine/sec2/base.o +nvkm-y += nvkm/engine/sec2/gp102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c new file mode 100644 index 000000000000..814daf35e21f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +#include +#include + +static void * +nvkm_sec2_dtor(struct nvkm_engine *engine) +{ + struct nvkm_sec2 *sec2 = nvkm_sec2(engine); + nvkm_msgqueue_del(&sec2->queue); + nvkm_falcon_del(&sec2->falcon); + return sec2; +} + +static void +nvkm_sec2_intr(struct nvkm_engine *engine) +{ + struct nvkm_sec2 *sec2 = nvkm_sec2(engine); + struct nvkm_subdev *subdev = &engine->subdev; + struct nvkm_device *device = subdev->device; + u32 disp = nvkm_rd32(device, 0x8701c); + u32 intr = nvkm_rd32(device, 0x87008) & disp & ~(disp >> 16); + + if (intr & 0x00000040) { + schedule_work(&sec2->work); + nvkm_wr32(device, 0x87004, 0x00000040); + intr &= ~0x00000040; + } + + if (intr) { + nvkm_error(subdev, "unhandled intr %08x\n", intr); + nvkm_wr32(device, 0x87004, intr); + + } +} + +static void +nvkm_sec2_recv(struct work_struct *work) +{ + struct nvkm_sec2 *sec2 = container_of(work, typeof(*sec2), work); + nvkm_msgqueue_recv(sec2->queue); +} + + +static int +nvkm_sec2_oneinit(struct nvkm_engine *engine) +{ + struct nvkm_sec2 *sec2 = nvkm_sec2(engine); + return nvkm_falcon_v1_new(&sec2->engine.subdev, "SEC2", 0x87000, + &sec2->falcon); +} + +static int +nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend) +{ + struct nvkm_sec2 *sec2 = nvkm_sec2(engine); + flush_work(&sec2->work); + return 0; +} + +static const struct nvkm_engine_func +nvkm_sec2 = { + .dtor = nvkm_sec2_dtor, + .oneinit = nvkm_sec2_oneinit, + .fini = nvkm_sec2_fini, + .intr = nvkm_sec2_intr, +}; + +int +nvkm_sec2_new_(struct nvkm_device *device, int index, + struct nvkm_sec2 **psec2) +{ + struct nvkm_sec2 *sec2; + + if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL))) + return -ENOMEM; + INIT_WORK(&sec2->work, nvkm_sec2_recv); + + return nvkm_engine_ctor(&nvkm_sec2, device, index, true, &sec2->engine); +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c new file mode 100644 index 000000000000..9be1524c08f5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "priv.h" + +int +gp102_sec2_new(struct nvkm_device *device, int index, + struct nvkm_sec2 **psec2) +{ + return nvkm_sec2_new_(device, index, psec2); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h new file mode 100644 index 000000000000..7ecc9d4724dc --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/priv.h @@ -0,0 +1,9 @@ +#ifndef __NVKM_SEC2_PRIV_H__ +#define __NVKM_SEC2_PRIV_H__ +#include + +#define nvkm_sec2(p) container_of((p), struct nvkm_sec2, engine) + +int nvkm_sec2_new_(struct nvkm_device *, int, struct nvkm_sec2 **); + +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c index efac3402f9dd..fea4957291da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c @@ -82,7 +82,7 @@ gk104_top_oneinit(struct nvkm_top *top) case 0x0000000a: A_(MSVLD ); break; case 0x0000000b: A_(MSENC ); break; case 0x0000000c: A_(VIC ); break; - case 0x0000000d: A_(SEC ); break; + case 0x0000000d: A_(SEC2 ); break; case 0x0000000e: B_(NVENC ); break; case 0x0000000f: A_(NVENC1); break; case 0x00000010: A_(NVDEC ); break; -- 2.20.1