summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm/subdev/mc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/mc')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c178
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c37
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c58
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c85
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c44
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c66
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h46
14 files changed, 292 insertions, 489 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
index 721643f04..bef325dcb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
@@ -1,11 +1,7 @@
nvkm-y += nvkm/subdev/mc/base.o
nvkm-y += nvkm/subdev/mc/nv04.o
-nvkm-y += nvkm/subdev/mc/nv40.o
nvkm-y += nvkm/subdev/mc/nv44.o
-nvkm-y += nvkm/subdev/mc/nv4c.o
nvkm-y += nvkm/subdev/mc/nv50.o
-nvkm-y += nvkm/subdev/mc/g94.o
nvkm-y += nvkm/subdev/mc/g98.o
nvkm-y += nvkm/subdev/mc/gf100.o
-nvkm-y += nvkm/subdev/mc/gf106.o
nvkm-y += nvkm/subdev/mc/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
index 5b051a266..954fbbe56 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
@@ -23,147 +23,101 @@
*/
#include "priv.h"
-#include <core/device.h>
#include <core/option.h>
-static inline void
-nvkm_mc_unk260(struct nvkm_mc *pmc, u32 data)
+void
+nvkm_mc_unk260(struct nvkm_mc *mc, u32 data)
{
- const struct nvkm_mc_oclass *impl = (void *)nv_oclass(pmc);
- if (impl->unk260)
- impl->unk260(pmc, data);
+ if (mc->func->unk260)
+ mc->func->unk260(mc, data);
}
-static inline u32
-nvkm_mc_intr_mask(struct nvkm_mc *pmc)
+void
+nvkm_mc_intr_unarm(struct nvkm_mc *mc)
{
- u32 intr = nv_rd32(pmc, 0x000100);
- if (intr == 0xffffffff) /* likely fallen off the bus */
- intr = 0x00000000;
- return intr;
+ return mc->func->intr_unarm(mc);
}
-static irqreturn_t
-nvkm_mc_intr(int irq, void *arg)
+void
+nvkm_mc_intr_rearm(struct nvkm_mc *mc)
{
- struct nvkm_mc *pmc = arg;
- const struct nvkm_mc_oclass *oclass = (void *)nv_object(pmc)->oclass;
- const struct nvkm_mc_intr *map = oclass->intr;
- struct nvkm_subdev *unit;
- u32 intr;
+ return mc->func->intr_rearm(mc);
+}
- nv_wr32(pmc, 0x000140, 0x00000000);
- nv_rd32(pmc, 0x000140);
- intr = nvkm_mc_intr_mask(pmc);
- if (pmc->use_msi)
- oclass->msi_rearm(pmc);
+static u32
+nvkm_mc_intr_mask(struct nvkm_mc *mc)
+{
+ u32 intr = mc->func->intr_mask(mc);
+ if (WARN_ON_ONCE(intr == 0xffffffff))
+ intr = 0; /* likely fallen off the bus */
+ return intr;
+}
- if (intr) {
- u32 stat = intr = nvkm_mc_intr_mask(pmc);
- while (map->stat) {
- if (intr & map->stat) {
- unit = nvkm_subdev(pmc, map->unit);
- if (unit && unit->intr)
- unit->intr(unit);
- stat &= ~map->stat;
- }
- map++;
+void
+nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
+{
+ struct nvkm_device *device = mc->subdev.device;
+ struct nvkm_subdev *subdev;
+ const struct nvkm_mc_intr *map = mc->func->intr;
+ u32 stat, intr;
+
+ stat = intr = nvkm_mc_intr_mask(mc);
+ while (map->stat) {
+ if (intr & map->stat) {
+ subdev = nvkm_device_subdev(device, map->unit);
+ if (subdev)
+ nvkm_subdev_intr(subdev);
+ stat &= ~map->stat;
}
-
- if (stat)
- nv_error(pmc, "unknown intr 0x%08x\n", stat);
+ map++;
}
- nv_wr32(pmc, 0x000140, 0x00000001);
- return intr ? IRQ_HANDLED : IRQ_NONE;
+ if (stat)
+ nvkm_error(&mc->subdev, "intr %08x\n", stat);
+ *handled = intr != 0;
}
-int
-_nvkm_mc_fini(struct nvkm_object *object, bool suspend)
+static int
+nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend)
{
- struct nvkm_mc *pmc = (void *)object;
- nv_wr32(pmc, 0x000140, 0x00000000);
- return nvkm_subdev_fini(&pmc->base, suspend);
+ struct nvkm_mc *mc = nvkm_mc(subdev);
+ nvkm_mc_intr_unarm(mc);
+ return 0;
}
-int
-_nvkm_mc_init(struct nvkm_object *object)
+static int
+nvkm_mc_init(struct nvkm_subdev *subdev)
{
- struct nvkm_mc *pmc = (void *)object;
- int ret = nvkm_subdev_init(&pmc->base);
- if (ret)
- return ret;
- nv_wr32(pmc, 0x000140, 0x00000001);
+ struct nvkm_mc *mc = nvkm_mc(subdev);
+ if (mc->func->init)
+ mc->func->init(mc);
+ nvkm_mc_intr_rearm(mc);
return 0;
}
-void
-_nvkm_mc_dtor(struct nvkm_object *object)
+static void *
+nvkm_mc_dtor(struct nvkm_subdev *subdev)
{
- struct nvkm_device *device = nv_device(object);
- struct nvkm_mc *pmc = (void *)object;
- free_irq(pmc->irq, pmc);
- if (pmc->use_msi)
- pci_disable_msi(device->pdev);
- nvkm_subdev_destroy(&pmc->base);
+ return nvkm_mc(subdev);
}
+static const struct nvkm_subdev_func
+nvkm_mc = {
+ .dtor = nvkm_mc_dtor,
+ .init = nvkm_mc_init,
+ .fini = nvkm_mc_fini,
+};
+
int
-nvkm_mc_create_(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *bclass, int length, void **pobject)
+nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device,
+ int index, struct nvkm_mc **pmc)
{
- const struct nvkm_mc_oclass *oclass = (void *)bclass;
- struct nvkm_device *device = nv_device(parent);
- struct nvkm_mc *pmc;
- int ret;
-
- ret = nvkm_subdev_create_(parent, engine, bclass, 0, "PMC",
- "master", length, pobject);
- pmc = *pobject;
- if (ret)
- return ret;
-
- pmc->unk260 = nvkm_mc_unk260;
-
- if (nv_device_is_pci(device)) {
- switch (device->pdev->device & 0x0ff0) {
- case 0x00f0:
- case 0x02e0:
- /* BR02? NFI how these would be handled yet exactly */
- break;
- default:
- switch (device->chipset) {
- case 0xaa:
- /* reported broken, nv also disable it */
- break;
- default:
- pmc->use_msi = true;
- break;
- }
- }
-
- pmc->use_msi = nvkm_boolopt(device->cfgopt, "NvMSI",
- pmc->use_msi);
-
- if (pmc->use_msi && oclass->msi_rearm) {
- pmc->use_msi = pci_enable_msi(device->pdev) == 0;
- if (pmc->use_msi) {
- nv_info(pmc, "MSI interrupts enabled\n");
- oclass->msi_rearm(pmc);
- }
- } else {
- pmc->use_msi = false;
- }
- }
-
- ret = nv_device_get_irq(device, true);
- if (ret < 0)
- return ret;
- pmc->irq = ret;
+ struct nvkm_mc *mc;
- ret = request_irq(pmc->irq, nvkm_mc_intr, IRQF_SHARED, "nvkm", pmc);
- if (ret < 0)
- return ret;
+ if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL)))
+ return -ENOMEM;
+ nvkm_subdev_ctor(&nvkm_mc, device, index, 0, &mc->subdev);
+ mc->func = func;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
deleted file mode 100644
index f042e7d83..000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 "nv04.h"
-
-struct nvkm_oclass *
-g94_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x94),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nvkm_mc_fini,
- },
- .intr = nv50_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
index 8ab7f1272..7344ad659 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
@@ -21,38 +21,40 @@
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
static const struct nvkm_mc_intr
g98_mc_intr[] = {
- { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */
- { 0x00000001, NVDEV_ENGINE_MSPPP },
- { 0x00000100, NVDEV_ENGINE_FIFO },
- { 0x00001000, NVDEV_ENGINE_GR },
- { 0x00004000, NVDEV_ENGINE_SEC }, /* NV84:NVA3 */
- { 0x00008000, NVDEV_ENGINE_MSVLD },
- { 0x00020000, NVDEV_ENGINE_MSPDEC },
- { 0x00040000, NVDEV_SUBDEV_PMU }, /* NVA3:NVC0 */
- { 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */
- { 0x00100000, NVDEV_SUBDEV_TIMER },
- { 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */
- { 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x00400000, NVDEV_ENGINE_CE0 }, /* NVA3- */
- { 0x10000000, NVDEV_SUBDEV_BUS },
- { 0x80000000, NVDEV_ENGINE_SW },
- { 0x0042d101, NVDEV_SUBDEV_FB },
+ { 0x04000000, NVKM_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */
+ { 0x00000001, NVKM_ENGINE_MSPPP },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00004000, NVKM_ENGINE_SEC }, /* NV84:NVA3 */
+ { 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00020000, NVKM_ENGINE_MSPDEC },
+ { 0x00040000, NVKM_SUBDEV_PMU }, /* NVA3:NVC0 */
+ { 0x00080000, NVKM_SUBDEV_THERM }, /* NVA3:NVC0 */
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */
+ { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */
+ { 0x00400000, NVKM_ENGINE_CE0 }, /* NVA3- */
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x80000000, NVKM_ENGINE_SW },
+ { 0x0042d101, NVKM_SUBDEV_FB },
{},
};
-struct nvkm_oclass *
-g98_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x98),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nvkm_mc_fini,
- },
+static const struct nvkm_mc_func
+g98_mc = {
+ .init = nv50_mc_init,
.intr = g98_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+};
+
+int
+g98_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&g98_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
index 2425984b0..122fe69e8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
@@ -21,56 +21,77 @@
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
const struct nvkm_mc_intr
gf100_mc_intr[] = {
- { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */
- { 0x00000001, NVDEV_ENGINE_MSPPP },
- { 0x00000020, NVDEV_ENGINE_CE0 },
- { 0x00000040, NVDEV_ENGINE_CE1 },
- { 0x00000080, NVDEV_ENGINE_CE2 },
- { 0x00000100, NVDEV_ENGINE_FIFO },
- { 0x00001000, NVDEV_ENGINE_GR },
- { 0x00002000, NVDEV_SUBDEV_FB },
- { 0x00008000, NVDEV_ENGINE_MSVLD },
- { 0x00040000, NVDEV_SUBDEV_THERM },
- { 0x00020000, NVDEV_ENGINE_MSPDEC },
- { 0x00100000, NVDEV_SUBDEV_TIMER },
- { 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */
- { 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x01000000, NVDEV_SUBDEV_PMU },
- { 0x02000000, NVDEV_SUBDEV_LTC },
- { 0x08000000, NVDEV_SUBDEV_FB },
- { 0x10000000, NVDEV_SUBDEV_BUS },
- { 0x40000000, NVDEV_SUBDEV_IBUS },
- { 0x80000000, NVDEV_ENGINE_SW },
+ { 0x04000000, NVKM_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */
+ { 0x00000001, NVKM_ENGINE_MSPPP },
+ { 0x00000020, NVKM_ENGINE_CE0 },
+ { 0x00000040, NVKM_ENGINE_CE1 },
+ { 0x00000080, NVKM_ENGINE_CE2 },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00002000, NVKM_SUBDEV_FB },
+ { 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00040000, NVKM_SUBDEV_THERM },
+ { 0x00020000, NVKM_ENGINE_MSPDEC },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */
+ { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */
+ { 0x01000000, NVKM_SUBDEV_PMU },
+ { 0x02000000, NVKM_SUBDEV_LTC },
+ { 0x08000000, NVKM_SUBDEV_FB },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x40000000, NVKM_SUBDEV_IBUS },
+ { 0x80000000, NVKM_ENGINE_SW },
{},
};
-static void
-gf100_mc_msi_rearm(struct nvkm_mc *pmc)
+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_mask(struct nvkm_mc *mc)
{
- struct nv04_mc_priv *priv = (void *)pmc;
- nv_wr32(priv, 0x088704, 0x00000000);
+ 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_unk260(struct nvkm_mc *pmc, u32 data)
+gf100_mc_unk260(struct nvkm_mc *mc, u32 data)
{
- nv_wr32(pmc, 0x000260, data);
+ nvkm_wr32(mc->subdev.device, 0x000260, data);
}
-struct nvkm_oclass *
-gf100_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0xc0),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nvkm_mc_fini,
- },
+static const struct nvkm_mc_func
+gf100_mc = {
+ .init = nv50_mc_init,
.intr = gf100_mc_intr,
- .msi_rearm = gf100_mc_msi_rearm,
+ .intr_unarm = gf100_mc_intr_unarm,
+ .intr_rearm = gf100_mc_intr_rearm,
+ .intr_mask = gf100_mc_intr_mask,
.unk260 = gf100_mc_unk260,
-}.base;
+};
+
+int
+gf100_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&gf100_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
deleted file mode 100644
index 8d2a8f457..000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 "nv04.h"
-
-struct nvkm_oclass *
-gf106_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0xc3),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nvkm_mc_fini,
- },
- .intr = gf100_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
- .unk260 = gf100_mc_unk260,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
index 43b277429..d92efb33b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
@@ -21,17 +21,19 @@
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
-struct nvkm_oclass *
-gk20a_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0xea),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nvkm_mc_fini,
- },
+static const struct nvkm_mc_func
+gk20a_mc = {
+ .init = nv50_mc_init,
.intr = gf100_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
+ .intr_unarm = gf100_mc_intr_unarm,
+ .intr_rearm = gf100_mc_intr_rearm,
+ .intr_mask = gf100_mc_intr_mask,
+};
+
+int
+gk20a_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&gk20a_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
index 32713827b..d282ec155 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
@@ -21,58 +21,63 @@
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
const struct nvkm_mc_intr
nv04_mc_intr[] = {
- { 0x00000001, NVDEV_ENGINE_MPEG }, /* NV17- MPEG/ME */
- { 0x00000100, NVDEV_ENGINE_FIFO },
- { 0x00001000, NVDEV_ENGINE_GR },
- { 0x00010000, NVDEV_ENGINE_DISP },
- { 0x00020000, NVDEV_ENGINE_VP }, /* NV40- */
- { 0x00100000, NVDEV_SUBDEV_TIMER },
- { 0x01000000, NVDEV_ENGINE_DISP }, /* NV04- PCRTC0 */
- { 0x02000000, NVDEV_ENGINE_DISP }, /* NV11- PCRTC1 */
- { 0x10000000, NVDEV_SUBDEV_BUS },
- { 0x80000000, NVDEV_ENGINE_SW },
+ { 0x00000001, NVKM_ENGINE_MPEG }, /* NV17- MPEG/ME */
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00010000, NVKM_ENGINE_DISP },
+ { 0x00020000, NVKM_ENGINE_VP }, /* NV40- */
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x01000000, NVKM_ENGINE_DISP }, /* NV04- PCRTC0 */
+ { 0x02000000, NVKM_ENGINE_DISP }, /* NV11- PCRTC1 */
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x80000000, NVKM_ENGINE_SW },
{}
};
-int
-nv04_mc_init(struct nvkm_object *object)
+void
+nv04_mc_intr_unarm(struct nvkm_mc *mc)
{
- struct nv04_mc_priv *priv = (void *)object;
-
- nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
- nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */
-
- return nvkm_mc_init(&priv->base);
+ struct nvkm_device *device = mc->subdev.device;
+ nvkm_wr32(device, 0x000140, 0x00000000);
+ nvkm_rd32(device, 0x000140);
}
-int
-nv04_mc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+void
+nv04_mc_intr_rearm(struct nvkm_mc *mc)
{
- struct nv04_mc_priv *priv;
- int ret;
+ struct nvkm_device *device = mc->subdev.device;
+ nvkm_wr32(device, 0x000140, 0x00000001);
+}
- ret = nvkm_mc_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
+u32
+nv04_mc_intr_mask(struct nvkm_mc *mc)
+{
+ return nvkm_rd32(mc->subdev.device, 0x000100);
+}
- return 0;
+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 */
}
-struct nvkm_oclass *
-nv04_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x04),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv04_mc_init,
- .fini = _nvkm_mc_fini,
- },
+static const struct nvkm_mc_func
+nv04_mc = {
+ .init = nv04_mc_init,
.intr = nv04_mc_intr,
-}.base;
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+};
+
+int
+nv04_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&nv04_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h
deleted file mode 100644
index 411de3d08..000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __NVKM_MC_NV04_H__
-#define __NVKM_MC_NV04_H__
-#include "priv.h"
-
-struct nv04_mc_priv {
- struct nvkm_mc base;
-};
-
-int nv04_mc_ctor(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, void *, u32,
- struct nvkm_object **);
-
-extern const struct nvkm_mc_intr nv04_mc_intr[];
-int nv04_mc_init(struct nvkm_object *);
-void nv40_mc_msi_rearm(struct nvkm_mc *);
-int nv44_mc_init(struct nvkm_object *object);
-int nv50_mc_init(struct nvkm_object *);
-extern const struct nvkm_mc_intr nv50_mc_intr[];
-extern const struct nvkm_mc_intr gf100_mc_intr[];
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
deleted file mode 100644
index b7613059d..000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 "nv04.h"
-
-void
-nv40_mc_msi_rearm(struct nvkm_mc *pmc)
-{
- struct nv04_mc_priv *priv = (void *)pmc;
- nv_wr08(priv, 0x088068, 0xff);
-}
-
-struct nvkm_oclass *
-nv40_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x40),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv04_mc_init,
- .fini = _nvkm_mc_fini,
- },
- .intr = nv04_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
index 2c7f7c701..9a3ac9965 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
@@ -21,33 +21,33 @@
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
+#include "priv.h"
-int
-nv44_mc_init(struct nvkm_object *object)
+void
+nv44_mc_init(struct nvkm_mc *mc)
{
- struct nv04_mc_priv *priv = (void *)object;
- u32 tmp = nv_rd32(priv, 0x10020c);
-
- nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
+ struct nvkm_device *device = mc->subdev.device;
+ u32 tmp = nvkm_rd32(device, 0x10020c);
- nv_wr32(priv, 0x001700, tmp);
- nv_wr32(priv, 0x001704, 0);
- nv_wr32(priv, 0x001708, 0);
- nv_wr32(priv, 0x00170c, tmp);
+ nvkm_wr32(device, 0x000200, 0xffffffff); /* everything enabled */
- return nvkm_mc_init(&priv->base);
+ nvkm_wr32(device, 0x001700, tmp);
+ nvkm_wr32(device, 0x001704, 0);
+ nvkm_wr32(device, 0x001708, 0);
+ nvkm_wr32(device, 0x00170c, tmp);
}
-struct nvkm_oclass *
-nv44_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x44),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv44_mc_init,
- .fini = _nvkm_mc_fini,
- },
+static const struct nvkm_mc_func
+nv44_mc = {
+ .init = nv44_mc_init,
.intr = nv04_mc_intr,
- .msi_rearm = nv40_mc_msi_rearm,
-}.base;
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+};
+
+int
+nv44_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&nv44_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
deleted file mode 100644
index c0aac7e20..000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2014 Ilia Mirkin
- *
- * 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: Ilia Mirkin
- */
-#include "nv04.h"
-
-struct nvkm_oclass *
-nv4c_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x4c),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv44_mc_init,
- .fini = _nvkm_mc_fini,
- },
- .intr = nv04_mc_intr,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
index 40e3019e1..5f27d7b8f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
@@ -21,52 +21,44 @@
*
* Authors: Ben Skeggs
*/
-#include "nv04.h"
-
-#include <core/device.h>
+#include "priv.h"
const struct nvkm_mc_intr
nv50_mc_intr[] = {
- { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */
- { 0x00000001, NVDEV_ENGINE_MPEG },
- { 0x00000100, NVDEV_ENGINE_FIFO },
- { 0x00001000, NVDEV_ENGINE_GR },
- { 0x00004000, NVDEV_ENGINE_CIPHER }, /* NV84- */
- { 0x00008000, NVDEV_ENGINE_BSP }, /* NV84- */
- { 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */
- { 0x00100000, NVDEV_SUBDEV_TIMER },
- { 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */
- { 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x10000000, NVDEV_SUBDEV_BUS },
- { 0x80000000, NVDEV_ENGINE_SW },
- { 0x0002d101, NVDEV_SUBDEV_FB },
+ { 0x04000000, NVKM_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */
+ { 0x00000001, NVKM_ENGINE_MPEG },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00004000, NVKM_ENGINE_CIPHER }, /* NV84- */
+ { 0x00008000, NVKM_ENGINE_BSP }, /* NV84- */
+ { 0x00020000, NVKM_ENGINE_VP }, /* NV84- */
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */
+ { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x80000000, NVKM_ENGINE_SW },
+ { 0x0002d101, NVKM_SUBDEV_FB },
{},
};
-static void
-nv50_mc_msi_rearm(struct nvkm_mc *pmc)
+void
+nv50_mc_init(struct nvkm_mc *mc)
{
- struct nvkm_device *device = nv_device(pmc);
- pci_write_config_byte(device->pdev, 0x68, 0xff);
+ 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_mask = nv04_mc_intr_mask,
+};
+
int
-nv50_mc_init(struct nvkm_object *object)
+nv50_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
{
- struct nv04_mc_priv *priv = (void *)object;
- nv_wr32(priv, 0x000200, 0xffffffff); /* everything on */
- return nvkm_mc_init(&priv->base);
+ return nvkm_mc_new_(&nv50_mc, device, index, pmc);
}
-
-struct nvkm_oclass *
-nv50_mc_oclass = &(struct nvkm_mc_oclass) {
- .base.handle = NV_SUBDEV(MC, 0x50),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_mc_ctor,
- .dtor = _nvkm_mc_dtor,
- .init = nv50_mc_init,
- .fini = _nvkm_mc_fini,
- },
- .intr = nv50_mc_intr,
- .msi_rearm = nv50_mc_msi_rearm,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
index d2cad07af..307f6c692 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
@@ -1,36 +1,42 @@
#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>
-#define nvkm_mc_create(p,e,o,d) \
- nvkm_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nvkm_mc_destroy(p) ({ \
- struct nvkm_mc *pmc = (p); _nvkm_mc_dtor(nv_object(pmc)); \
-})
-#define nvkm_mc_init(p) ({ \
- struct nvkm_mc *pmc = (p); _nvkm_mc_init(nv_object(pmc)); \
-})
-#define nvkm_mc_fini(p,s) ({ \
- struct nvkm_mc *pmc = (p); _nvkm_mc_fini(nv_object(pmc), (s)); \
-})
-
-int nvkm_mc_create_(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, int, void **);
-void _nvkm_mc_dtor(struct nvkm_object *);
-int _nvkm_mc_init(struct nvkm_object *);
-int _nvkm_mc_fini(struct nvkm_object *, bool);
+int nvkm_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *,
+ int index, struct nvkm_mc **);
struct nvkm_mc_intr {
u32 stat;
u32 unit;
};
-struct nvkm_mc_oclass {
- struct nvkm_oclass base;
+struct nvkm_mc_func {
+ void (*init)(struct nvkm_mc *);
const struct nvkm_mc_intr *intr;
- void (*msi_rearm)(struct nvkm_mc *);
+ /* disable reporting of interrupts to host */
+ void (*intr_unarm)(struct nvkm_mc *);
+ /* enable reporting of interrupts to host */
+ void (*intr_rearm)(struct nvkm_mc *);
+ /* retrieve pending interrupt mask (NV_PMC_INTR) */
+ u32 (*intr_mask)(struct nvkm_mc *);
void (*unk260)(struct nvkm_mc *, u32);
};
+void nv04_mc_init(struct nvkm_mc *);
+extern const struct nvkm_mc_intr nv04_mc_intr[];
+void nv04_mc_intr_unarm(struct nvkm_mc *);
+void nv04_mc_intr_rearm(struct nvkm_mc *);
+u32 nv04_mc_intr_mask(struct nvkm_mc *);
+
+void nv44_mc_init(struct nvkm_mc *);
+
+void nv50_mc_init(struct nvkm_mc *);
+extern const struct nvkm_mc_intr nv50_mc_intr[];
+
+extern const struct nvkm_mc_intr gf100_mc_intr[];
+void gf100_mc_intr_unarm(struct nvkm_mc *);
+void gf100_mc_intr_rearm(struct nvkm_mc *);
+u32 gf100_mc_intr_mask(struct nvkm_mc *);
void gf100_mc_unk260(struct nvkm_mc *, u32);
#endif