drm/nouveau/mc: add helper function to handle device reset

This will be later extended to handle PTOP-specified reset masks as well
as the hardcoded ones.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2016-04-08 17:24:40 +10:00
Родитель 87f313e6e6
Коммит 6defde5ab3
3 изменённых файлов: 23 добавлений и 6 удалений

Просмотреть файл

@ -10,6 +10,7 @@ struct nvkm_mc {
void nvkm_mc_intr(struct nvkm_mc *, bool *handled);
void nvkm_mc_intr_unarm(struct nvkm_mc *);
void nvkm_mc_intr_rearm(struct nvkm_mc *);
void nvkm_mc_reset(struct nvkm_mc *, enum nvkm_devidx);
void nvkm_mc_unk260(struct nvkm_mc *, u32 data);
int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **);

Просмотреть файл

@ -24,6 +24,7 @@
#include <core/subdev.h>
#include <core/device.h>
#include <core/option.h>
#include <subdev/mc.h>
static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR];
@ -90,7 +91,6 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct nvkm_device *device = subdev->device;
const char *action = suspend ? "suspend" : "fini";
u32 pmc_enable = subdev->pmc_enable;
s64 time;
nvkm_trace(subdev, "%s running...\n", action);
@ -105,11 +105,7 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
}
}
if (pmc_enable) {
nvkm_mask(device, 0x000200, pmc_enable, 0x00000000);
nvkm_mask(device, 0x000200, pmc_enable, pmc_enable);
nvkm_rd32(device, 0x000200);
}
nvkm_mc_reset(device->mc, subdev->index);
time = ktime_to_us(ktime_get()) - time;
nvkm_trace(subdev, "%s completed in %lldus\n", action, time);

Просмотреть файл

@ -77,6 +77,26 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
*handled = intr != 0;
}
static void
nvkm_mc_reset_(struct nvkm_mc *mc, enum nvkm_devidx devidx)
{
struct nvkm_device *device = mc->subdev.device;
struct nvkm_subdev *subdev = nvkm_device_subdev(device, devidx);
u64 pmc_enable = subdev->pmc_enable;
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_reset(struct nvkm_mc *mc, enum nvkm_devidx devidx)
{
if (likely(mc))
nvkm_mc_reset_(mc, devidx);
}
static int
nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend)
{