diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/mc')
18 files changed, 1442 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild new file mode 100644 index 000000000..ac2b34e9a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: MIT +nvkm-y += nvkm/subdev/mc/base.o +nvkm-y += nvkm/subdev/mc/nv04.o +nvkm-y += nvkm/subdev/mc/nv11.o +nvkm-y += nvkm/subdev/mc/nv17.o +nvkm-y += nvkm/subdev/mc/nv44.o +nvkm-y += nvkm/subdev/mc/nv50.o +nvkm-y += nvkm/subdev/mc/g84.o +nvkm-y += nvkm/subdev/mc/g98.o +nvkm-y += nvkm/subdev/mc/gt215.o +nvkm-y += nvkm/subdev/mc/gf100.o +nvkm-y += nvkm/subdev/mc/gk104.o +nvkm-y += nvkm/subdev/mc/gk20a.o +nvkm-y += nvkm/subdev/mc/gp100.o +nvkm-y += nvkm/subdev/mc/gp10b.o +nvkm-y += nvkm/subdev/mc/tu102.o +nvkm-y += nvkm/subdev/mc/ga100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c new file mode 100644 index 000000000..21c4af3f8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c @@ -0,0 +1,227 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +#include <core/option.h> +#include <subdev/top.h> + +void +nvkm_mc_unk260(struct nvkm_device *device, u32 data) +{ + struct nvkm_mc *mc = device->mc; + if (likely(mc) && mc->func->unk260) + mc->func->unk260(mc, data); +} + +void +nvkm_mc_intr_mask(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, bool en) +{ + struct nvkm_mc *mc = device->mc; + const struct nvkm_mc_map *map; + if (likely(mc) && mc->func->intr_mask) { + u32 mask = nvkm_top_intr_mask(device, type, inst); + for (map = mc->func->intr; !mask && map->stat; map++) { + if (map->type == type && map->inst == inst) + mask = map->stat; + } + mc->func->intr_mask(mc, mask, en ? mask : 0); + } +} + +void +nvkm_mc_intr_unarm(struct nvkm_device *device) +{ + struct nvkm_mc *mc = device->mc; + if (likely(mc)) + mc->func->intr_unarm(mc); +} + +void +nvkm_mc_intr_rearm(struct nvkm_device *device) +{ + struct nvkm_mc *mc = device->mc; + if (likely(mc)) + mc->func->intr_rearm(mc); +} + +static u32 +nvkm_mc_intr_stat(struct nvkm_mc *mc) +{ + u32 intr = mc->func->intr_stat(mc); + if (WARN_ON_ONCE(intr == 0xffffffff)) + intr = 0; /* likely fallen off the bus */ + return intr; +} + +void +nvkm_mc_intr(struct nvkm_device *device, bool *handled) +{ + struct nvkm_mc *mc = device->mc; + struct nvkm_top *top = device->top; + struct nvkm_top_device *tdev; + struct nvkm_subdev *subdev; + const struct nvkm_mc_map *map; + u32 stat, intr; + + if (unlikely(!mc)) + return; + + stat = intr = nvkm_mc_intr_stat(mc); + + if (top) { + list_for_each_entry(tdev, &top->device, head) { + if (tdev->intr >= 0 && (stat & BIT(tdev->intr))) { + subdev = nvkm_device_subdev(device, tdev->type, tdev->inst); + if (subdev) { + nvkm_subdev_intr(subdev); + stat &= ~BIT(tdev->intr); + if (!stat) + break; + } + } + } + } + + for (map = mc->func->intr; map->stat; map++) { + if (intr & map->stat) { + subdev = nvkm_device_subdev(device, map->type, map->inst); + if (subdev) + nvkm_subdev_intr(subdev); + stat &= ~map->stat; + } + } + + if (stat) + nvkm_error(&mc->subdev, "intr %08x\n", stat); + *handled = intr != 0; +} + +static u32 +nvkm_mc_reset_mask(struct nvkm_device *device, bool isauto, enum nvkm_subdev_type type, int inst) +{ + struct nvkm_mc *mc = device->mc; + const struct nvkm_mc_map *map; + u64 pmc_enable = 0; + if (likely(mc)) { + if (!(pmc_enable = nvkm_top_reset(device, type, inst))) { + for (map = mc->func->reset; map && map->stat; map++) { + if (!isauto || !map->noauto) { + if (map->type == type && map->inst == inst) { + pmc_enable = map->stat; + break; + } + } + } + } + } + return pmc_enable; +} + +void +nvkm_mc_reset(struct nvkm_device *device, enum nvkm_subdev_type type, int inst) +{ + u64 pmc_enable = nvkm_mc_reset_mask(device, true, type, inst); + if (pmc_enable) { + nvkm_mask(device, 0x000200, pmc_enable, 0x00000000); + nvkm_mask(device, 0x000200, pmc_enable, pmc_enable); + nvkm_rd32(device, 0x000200); + } +} + +void +nvkm_mc_disable(struct nvkm_device *device, enum nvkm_subdev_type type, int inst) +{ + u64 pmc_enable = nvkm_mc_reset_mask(device, false, type, inst); + if (pmc_enable) + nvkm_mask(device, 0x000200, pmc_enable, 0x00000000); +} + +void +nvkm_mc_enable(struct nvkm_device *device, enum nvkm_subdev_type type, int inst) +{ + u64 pmc_enable = nvkm_mc_reset_mask(device, false, type, inst); + if (pmc_enable) { + nvkm_mask(device, 0x000200, pmc_enable, pmc_enable); + nvkm_rd32(device, 0x000200); + } +} + +bool +nvkm_mc_enabled(struct nvkm_device *device, enum nvkm_subdev_type type, int inst) +{ + u64 pmc_enable = nvkm_mc_reset_mask(device, false, type, inst); + + return (pmc_enable != 0) && + ((nvkm_rd32(device, 0x000200) & pmc_enable) == pmc_enable); +} + + +static int +nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend) +{ + nvkm_mc_intr_unarm(subdev->device); + return 0; +} + +static int +nvkm_mc_init(struct nvkm_subdev *subdev) +{ + struct nvkm_mc *mc = nvkm_mc(subdev); + if (mc->func->init) + mc->func->init(mc); + nvkm_mc_intr_rearm(subdev->device); + return 0; +} + +static void * +nvkm_mc_dtor(struct nvkm_subdev *subdev) +{ + return nvkm_mc(subdev); +} + +static const struct nvkm_subdev_func +nvkm_mc = { + .dtor = nvkm_mc_dtor, + .init = nvkm_mc_init, + .fini = nvkm_mc_fini, +}; + +void +nvkm_mc_ctor(const struct nvkm_mc_func *func, struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_mc *mc) +{ + nvkm_subdev_ctor(&nvkm_mc, device, type, inst, &mc->subdev); + mc->func = func; +} + +int +nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + struct nvkm_mc *mc; + if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL))) + return -ENOMEM; + nvkm_mc_ctor(func, device, type, inst, *pmc); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c new file mode 100644 index 000000000..4cfc1c984 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +g84_mc_reset[] = { + { 0x04008000, NVKM_ENGINE_BSP }, + { 0x02004000, NVKM_ENGINE_CIPHER }, + { 0x01020000, NVKM_ENGINE_VP }, + { 0x00400002, NVKM_ENGINE_MPEG }, + { 0x00201000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +static const struct nvkm_mc_map +g84_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00020000, NVKM_ENGINE_VP }, + { 0x00008000, NVKM_ENGINE_BSP }, + { 0x00004000, NVKM_ENGINE_CIPHER }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MPEG }, + { 0x0002d101, NVKM_SUBDEV_FB }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {}, +}; + +static const struct nvkm_mc_func +g84_mc = { + .init = nv50_mc_init, + .intr = g84_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = g84_mc_reset, +}; + +int +g84_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&g84_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c new file mode 100644 index 000000000..b7e58d75d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +g98_mc_reset[] = { + { 0x04008000, NVKM_ENGINE_MSVLD }, + { 0x02004000, NVKM_ENGINE_SEC }, + { 0x01020000, NVKM_ENGINE_MSPDEC }, + { 0x00400002, NVKM_ENGINE_MSPPP }, + { 0x00201000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +static const struct nvkm_mc_map +g98_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00020000, NVKM_ENGINE_MSPDEC }, + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00004000, NVKM_ENGINE_SEC }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MSPPP }, + { 0x0002d101, NVKM_SUBDEV_FB }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {}, +}; + +static const struct nvkm_mc_func +g98_mc = { + .init = nv50_mc_init, + .intr = g98_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = g98_mc_reset, +}; + +int +g98_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&g98_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c new file mode 100644 index 000000000..4105175df --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/ga100.c @@ -0,0 +1,74 @@ +/* + * Copyright 2021 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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" + +static void +ga100_mc_intr_unarm(struct nvkm_mc *mc) +{ + nvkm_wr32(mc->subdev.device, 0xb81610, 0x00000004); +} + +static void +ga100_mc_intr_rearm(struct nvkm_mc *mc) +{ + nvkm_wr32(mc->subdev.device, 0xb81608, 0x00000004); +} + +static void +ga100_mc_intr_mask(struct nvkm_mc *mc, u32 mask, u32 intr) +{ + nvkm_wr32(mc->subdev.device, 0xb81210, mask & intr ); + nvkm_wr32(mc->subdev.device, 0xb81410, mask & ~(mask & intr)); +} + +static u32 +ga100_mc_intr_stat(struct nvkm_mc *mc) +{ + u32 intr_top = nvkm_rd32(mc->subdev.device, 0xb81600), intr = 0x00000000; + if (intr_top & 0x00000004) + intr = nvkm_mask(mc->subdev.device, 0xb81010, 0x00000000, 0x00000000); + return intr; +} + +static void +ga100_mc_init(struct nvkm_mc *mc) +{ + nv50_mc_init(mc); + nvkm_wr32(mc->subdev.device, 0xb81210, 0xffffffff); +} + +static const struct nvkm_mc_func +ga100_mc = { + .init = ga100_mc_init, + .intr = gp100_mc_intr, + .intr_unarm = ga100_mc_intr_unarm, + .intr_rearm = ga100_mc_intr_rearm, + .intr_mask = ga100_mc_intr_mask, + .intr_stat = ga100_mc_intr_stat, + .reset = gk104_mc_reset, +}; + +int +ga100_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&ga100_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c new file mode 100644 index 000000000..3a589c6f7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c @@ -0,0 +1,118 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +gf100_mc_reset[] = { + { 0x00020000, NVKM_ENGINE_MSPDEC }, + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00002000, NVKM_SUBDEV_PMU, 0, true }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000080, NVKM_ENGINE_CE, 1 }, + { 0x00000040, NVKM_ENGINE_CE, 0 }, + { 0x00000002, NVKM_ENGINE_MSPPP }, + {} +}; + +static const struct nvkm_mc_map +gf100_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00020000, NVKM_ENGINE_MSPDEC }, + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000040, NVKM_ENGINE_CE, 1 }, + { 0x00000020, NVKM_ENGINE_CE, 0 }, + { 0x00000001, NVKM_ENGINE_MSPPP }, + { 0x40000000, NVKM_SUBDEV_PRIVRING }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x08000000, NVKM_SUBDEV_FB }, + { 0x02000000, NVKM_SUBDEV_LTC }, + { 0x01000000, NVKM_SUBDEV_PMU }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00002000, NVKM_SUBDEV_FB }, + {}, +}; + +void +gf100_mc_intr_unarm(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000140, 0x00000000); + nvkm_wr32(device, 0x000144, 0x00000000); + nvkm_rd32(device, 0x000140); +} + +void +gf100_mc_intr_rearm(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000140, 0x00000001); + nvkm_wr32(device, 0x000144, 0x00000001); +} + +u32 +gf100_mc_intr_stat(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + u32 intr0 = nvkm_rd32(device, 0x000100); + u32 intr1 = nvkm_rd32(device, 0x000104); + return intr0 | intr1; +} + +void +gf100_mc_intr_mask(struct nvkm_mc *mc, u32 mask, u32 stat) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_mask(device, 0x000640, mask, stat); + nvkm_mask(device, 0x000644, mask, stat); +} + +void +gf100_mc_unk260(struct nvkm_mc *mc, u32 data) +{ + nvkm_wr32(mc->subdev.device, 0x000260, data); +} + +static const struct nvkm_mc_func +gf100_mc = { + .init = nv50_mc_init, + .intr = gf100_mc_intr, + .intr_unarm = gf100_mc_intr_unarm, + .intr_rearm = gf100_mc_intr_rearm, + .intr_mask = gf100_mc_intr_mask, + .intr_stat = gf100_mc_intr_stat, + .reset = gf100_mc_reset, + .unk260 = gf100_mc_unk260, +}; + +int +gf100_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&gf100_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c new file mode 100644 index 000000000..d9b9067fa --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +const struct nvkm_mc_map +gk104_mc_reset[] = { + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00002000, NVKM_SUBDEV_PMU, 0, true }, + {} +}; + +const struct nvkm_mc_map +gk104_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x40000000, NVKM_SUBDEV_PRIVRING }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x08000000, NVKM_SUBDEV_FB }, + { 0x02000000, NVKM_SUBDEV_LTC }, + { 0x01000000, NVKM_SUBDEV_PMU }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00002000, NVKM_SUBDEV_FB }, + {}, +}; + +static const struct nvkm_mc_func +gk104_mc = { + .init = nv50_mc_init, + .intr = gk104_mc_intr, + .intr_unarm = gf100_mc_intr_unarm, + .intr_rearm = gf100_mc_intr_rearm, + .intr_mask = gf100_mc_intr_mask, + .intr_stat = gf100_mc_intr_stat, + .reset = gk104_mc_reset, + .unk260 = gf100_mc_unk260, +}; + +int +gk104_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&gk104_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c new file mode 100644 index 000000000..035902927 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c @@ -0,0 +1,41 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_func +gk20a_mc = { + .init = nv50_mc_init, + .intr = gk104_mc_intr, + .intr_unarm = gf100_mc_intr_unarm, + .intr_rearm = gf100_mc_intr_rearm, + .intr_mask = gf100_mc_intr_mask, + .intr_stat = gf100_mc_intr_stat, + .reset = gk104_mc_reset, +}; + +int +gk20a_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&gk20a_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c new file mode 100644 index 000000000..5fd1a0595 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c @@ -0,0 +1,128 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#define gp100_mc(p) container_of((p), struct gp100_mc, base) +#include "priv.h" + +struct gp100_mc { + struct nvkm_mc base; + spinlock_t lock; + bool intr; + u32 mask; +}; + +static void +gp100_mc_intr_update(struct gp100_mc *mc) +{ + struct nvkm_device *device = mc->base.subdev.device; + u32 mask = mc->intr ? mc->mask : 0, i; + for (i = 0; i < 2; i++) { + nvkm_wr32(device, 0x000180 + (i * 0x04), ~mask); + nvkm_wr32(device, 0x000160 + (i * 0x04), mask); + } +} + +void +gp100_mc_intr_unarm(struct nvkm_mc *base) +{ + struct gp100_mc *mc = gp100_mc(base); + unsigned long flags; + spin_lock_irqsave(&mc->lock, flags); + mc->intr = false; + gp100_mc_intr_update(mc); + spin_unlock_irqrestore(&mc->lock, flags); +} + +void +gp100_mc_intr_rearm(struct nvkm_mc *base) +{ + struct gp100_mc *mc = gp100_mc(base); + unsigned long flags; + spin_lock_irqsave(&mc->lock, flags); + mc->intr = true; + gp100_mc_intr_update(mc); + spin_unlock_irqrestore(&mc->lock, flags); +} + +void +gp100_mc_intr_mask(struct nvkm_mc *base, u32 mask, u32 intr) +{ + struct gp100_mc *mc = gp100_mc(base); + unsigned long flags; + spin_lock_irqsave(&mc->lock, flags); + mc->mask = (mc->mask & ~mask) | intr; + gp100_mc_intr_update(mc); + spin_unlock_irqrestore(&mc->lock, flags); +} + +const struct nvkm_mc_map +gp100_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000200, NVKM_SUBDEV_FAULT }, + { 0x40000000, NVKM_SUBDEV_PRIVRING }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x08000000, NVKM_SUBDEV_FB }, + { 0x02000000, NVKM_SUBDEV_LTC }, + { 0x01000000, NVKM_SUBDEV_PMU }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00002000, NVKM_SUBDEV_FB }, + {}, +}; + +static const struct nvkm_mc_func +gp100_mc = { + .init = nv50_mc_init, + .intr = gp100_mc_intr, + .intr_unarm = gp100_mc_intr_unarm, + .intr_rearm = gp100_mc_intr_rearm, + .intr_mask = gp100_mc_intr_mask, + .intr_stat = gf100_mc_intr_stat, + .reset = gk104_mc_reset, +}; + +int +gp100_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + struct gp100_mc *mc; + + if (!(mc = kzalloc(sizeof(*mc), GFP_KERNEL))) + return -ENOMEM; + nvkm_mc_ctor(func, device, type, inst, &mc->base); + *pmc = &mc->base; + + spin_lock_init(&mc->lock); + mc->intr = false; + mc->mask = 0x7fffffff; + return 0; +} + +int +gp100_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return gp100_mc_new_(&gp100_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c new file mode 100644 index 000000000..dd581d030 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c @@ -0,0 +1,49 @@ +/* + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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" + +static void +gp10b_mc_init(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000200, 0xffffffff); /* everything on */ + nvkm_wr32(device, 0x00020c, 0xffffffff); /* everything out of ELPG */ +} + +static const struct nvkm_mc_func +gp10b_mc = { + .init = gp10b_mc_init, + .intr = gp100_mc_intr, + .intr_unarm = gp100_mc_intr_unarm, + .intr_rearm = gp100_mc_intr_rearm, + .intr_mask = gp100_mc_intr_mask, + .intr_stat = gf100_mc_intr_stat, + .reset = gk104_mc_reset, +}; + +int +gp10b_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return gp100_mc_new_(&gp10b_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c new file mode 100644 index 000000000..1b4d43531 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c @@ -0,0 +1,77 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +gt215_mc_reset[] = { + { 0x04008000, NVKM_ENGINE_MSVLD }, + { 0x01020000, NVKM_ENGINE_MSPDEC }, + { 0x00802000, NVKM_ENGINE_CE, 0 }, + { 0x00400002, NVKM_ENGINE_MSPPP }, + { 0x00201000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +static const struct nvkm_mc_map +gt215_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00400000, NVKM_ENGINE_CE, 0 }, + { 0x00020000, NVKM_ENGINE_MSPDEC }, + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MSPPP }, + { 0x00429101, NVKM_SUBDEV_FB }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00080000, NVKM_SUBDEV_THERM }, + { 0x00040000, NVKM_SUBDEV_PMU }, + {}, +}; + +static void +gt215_mc_intr_mask(struct nvkm_mc *mc, u32 mask, u32 stat) +{ + nvkm_mask(mc->subdev.device, 0x000640, mask, stat); +} + +static const struct nvkm_mc_func +gt215_mc = { + .init = nv50_mc_init, + .intr = gt215_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_mask = gt215_mc_intr_mask, + .intr_stat = nv04_mc_intr_stat, + .reset = gt215_mc_reset, +}; + +int +gt215_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(>215_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c new file mode 100644 index 000000000..bc0d09baf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c @@ -0,0 +1,86 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +const struct nvkm_mc_map +nv04_mc_reset[] = { + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +static const struct nvkm_mc_map +nv04_mc_intr[] = { + { 0x01010000, NVKM_ENGINE_DISP }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {} +}; + +void +nv04_mc_intr_unarm(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000140, 0x00000000); + nvkm_rd32(device, 0x000140); +} + +void +nv04_mc_intr_rearm(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000140, 0x00000001); +} + +u32 +nv04_mc_intr_stat(struct nvkm_mc *mc) +{ + return nvkm_rd32(mc->subdev.device, 0x000100); +} + +void +nv04_mc_init(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000200, 0xffffffff); /* everything enabled */ + nvkm_wr32(device, 0x001850, 0x00000001); /* disable rom access */ +} + +static const struct nvkm_mc_func +nv04_mc = { + .init = nv04_mc_init, + .intr = nv04_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = nv04_mc_reset, +}; + +int +nv04_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv04_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c new file mode 100644 index 000000000..ab59ca1ee --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ +#include "priv.h" + +static const struct nvkm_mc_map +nv11_mc_intr[] = { + { 0x03010000, NVKM_ENGINE_DISP }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {} +}; + +static const struct nvkm_mc_func +nv11_mc = { + .init = nv04_mc_init, + .intr = nv11_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = nv04_mc_reset, +}; + +int +nv11_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv11_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c new file mode 100644 index 000000000..03d756e26 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ +#include "priv.h" + +const struct nvkm_mc_map +nv17_mc_reset[] = { + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000002, NVKM_ENGINE_MPEG }, + {} +}; + +const struct nvkm_mc_map +nv17_mc_intr[] = { + { 0x03010000, NVKM_ENGINE_DISP }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MPEG }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {} +}; + +static const struct nvkm_mc_func +nv17_mc = { + .init = nv04_mc_init, + .intr = nv17_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = nv17_mc_reset, +}; + +int +nv17_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv17_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c new file mode 100644 index 000000000..95f65766e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +void +nv44_mc_init(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + u32 tmp = nvkm_rd32(device, 0x10020c); + + nvkm_wr32(device, 0x000200, 0xffffffff); /* everything enabled */ + + nvkm_wr32(device, 0x001700, tmp); + nvkm_wr32(device, 0x001704, 0); + nvkm_wr32(device, 0x001708, 0); + nvkm_wr32(device, 0x00170c, tmp); +} + +static const struct nvkm_mc_func +nv44_mc = { + .init = nv44_mc_init, + .intr = nv17_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = nv17_mc_reset, +}; + +int +nv44_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv44_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c new file mode 100644 index 000000000..fce3613cd --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c @@ -0,0 +1,61 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +nv50_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MPEG }, + { 0x00001101, NVKM_SUBDEV_FB }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {}, +}; + +void +nv50_mc_init(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + nvkm_wr32(device, 0x000200, 0xffffffff); /* everything on */ +} + +static const struct nvkm_mc_func +nv50_mc = { + .init = nv50_mc_init, + .intr = nv50_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_stat = nv04_mc_intr_stat, + .reset = nv17_mc_reset, +}; + +int +nv50_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv50_mc, device, type, inst, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h new file mode 100644 index 000000000..c8bcabb98 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_MC_PRIV_H__ +#define __NVKM_MC_PRIV_H__ +#define nvkm_mc(p) container_of((p), struct nvkm_mc, subdev) +#include <subdev/mc.h> + +void nvkm_mc_ctor(const struct nvkm_mc_func *, struct nvkm_device *, enum nvkm_subdev_type, int, + struct nvkm_mc *); +int nvkm_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *, enum nvkm_subdev_type, int, + struct nvkm_mc **); + +struct nvkm_mc_map { + u32 stat; + enum nvkm_subdev_type type; + int inst; + bool noauto; +}; + +struct nvkm_mc_func { + void (*init)(struct nvkm_mc *); + const struct nvkm_mc_map *intr; + /* disable reporting of interrupts to host */ + void (*intr_unarm)(struct nvkm_mc *); + /* enable reporting of interrupts to host */ + void (*intr_rearm)(struct nvkm_mc *); + /* (un)mask delivery of specific interrupts */ + void (*intr_mask)(struct nvkm_mc *, u32 mask, u32 stat); + /* retrieve pending interrupt mask (NV_PMC_INTR) */ + u32 (*intr_stat)(struct nvkm_mc *); + const struct nvkm_mc_map *reset; + void (*unk260)(struct nvkm_mc *, u32); +}; + +void nv04_mc_init(struct nvkm_mc *); +void nv04_mc_intr_unarm(struct nvkm_mc *); +void nv04_mc_intr_rearm(struct nvkm_mc *); +u32 nv04_mc_intr_stat(struct nvkm_mc *); +extern const struct nvkm_mc_map nv04_mc_reset[]; + +extern const struct nvkm_mc_map nv17_mc_intr[]; +extern const struct nvkm_mc_map nv17_mc_reset[]; + +void nv44_mc_init(struct nvkm_mc *); + +void nv50_mc_init(struct nvkm_mc *); +void gk104_mc_init(struct nvkm_mc *); + +void gf100_mc_intr_unarm(struct nvkm_mc *); +void gf100_mc_intr_rearm(struct nvkm_mc *); +void gf100_mc_intr_mask(struct nvkm_mc *, u32, u32); +u32 gf100_mc_intr_stat(struct nvkm_mc *); +void gf100_mc_unk260(struct nvkm_mc *, u32); +void gp100_mc_intr_unarm(struct nvkm_mc *); +void gp100_mc_intr_rearm(struct nvkm_mc *); +void gp100_mc_intr_mask(struct nvkm_mc *, u32, u32); +int gp100_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *, enum nvkm_subdev_type, int, + struct nvkm_mc **); + +extern const struct nvkm_mc_map gk104_mc_intr[]; +extern const struct nvkm_mc_map gk104_mc_reset[]; + +extern const struct nvkm_mc_map gp100_mc_intr[]; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/tu102.c new file mode 100644 index 000000000..a96084b34 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/tu102.c @@ -0,0 +1,136 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + */ +#define tu102_mc(p) container_of((p), struct tu102_mc, base) +#include "priv.h" + +struct tu102_mc { + struct nvkm_mc base; + spinlock_t lock; + bool intr; + u32 mask; +}; + +static void +tu102_mc_intr_update(struct tu102_mc *mc) +{ + struct nvkm_device *device = mc->base.subdev.device; + u32 mask = mc->intr ? mc->mask : 0, i; + + for (i = 0; i < 2; i++) { + nvkm_wr32(device, 0x000180 + (i * 0x04), ~mask); + nvkm_wr32(device, 0x000160 + (i * 0x04), mask); + } + + if (mask & 0x00000200) + nvkm_wr32(device, 0xb81608, 0x6); + else + nvkm_wr32(device, 0xb81610, 0x6); +} + +static void +tu102_mc_intr_unarm(struct nvkm_mc *base) +{ + struct tu102_mc *mc = tu102_mc(base); + unsigned long flags; + + spin_lock_irqsave(&mc->lock, flags); + mc->intr = false; + tu102_mc_intr_update(mc); + spin_unlock_irqrestore(&mc->lock, flags); +} + +static void +tu102_mc_intr_rearm(struct nvkm_mc *base) +{ + struct tu102_mc *mc = tu102_mc(base); + unsigned long flags; + + spin_lock_irqsave(&mc->lock, flags); + mc->intr = true; + tu102_mc_intr_update(mc); + spin_unlock_irqrestore(&mc->lock, flags); +} + +static void +tu102_mc_intr_mask(struct nvkm_mc *base, u32 mask, u32 intr) +{ + struct tu102_mc *mc = tu102_mc(base); + unsigned long flags; + + spin_lock_irqsave(&mc->lock, flags); + mc->mask = (mc->mask & ~mask) | intr; + tu102_mc_intr_update(mc); + spin_unlock_irqrestore(&mc->lock, flags); +} + +static u32 +tu102_mc_intr_stat(struct nvkm_mc *mc) +{ + struct nvkm_device *device = mc->subdev.device; + u32 intr0 = nvkm_rd32(device, 0x000100); + u32 intr1 = nvkm_rd32(device, 0x000104); + u32 intr_top = nvkm_rd32(device, 0xb81600); + + /* Turing and above route the MMU fault interrupts via a different + * interrupt tree with different control registers. For the moment remap + * them back to the old PMC vector. + */ + if (intr_top & 0x00000006) + intr0 |= 0x00000200; + + return intr0 | intr1; +} + + +static const struct nvkm_mc_func +tu102_mc = { + .init = nv50_mc_init, + .intr = gp100_mc_intr, + .intr_unarm = tu102_mc_intr_unarm, + .intr_rearm = tu102_mc_intr_rearm, + .intr_mask = tu102_mc_intr_mask, + .intr_stat = tu102_mc_intr_stat, + .reset = gk104_mc_reset, +}; + +static int +tu102_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + struct tu102_mc *mc; + + if (!(mc = kzalloc(sizeof(*mc), GFP_KERNEL))) + return -ENOMEM; + nvkm_mc_ctor(func, device, type, inst, &mc->base); + *pmc = &mc->base; + + spin_lock_init(&mc->lock); + mc->intr = false; + mc->mask = 0x7fffffff; + return 0; +} + +int +tu102_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc) +{ + return tu102_mc_new_(&tu102_mc, device, type, inst, pmc); +} |