forked from Minki/linux
drm/nouveau/fault/gp100: expose MaxwellFaultBufferA
This nvclass exposes the replayable fault buffer, which will be used by SVM to manage GPU page faults. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
ab2ee9ffa3
commit
13e9572906
@ -54,6 +54,8 @@
|
||||
|
||||
#define VOLTA_USERMODE_A 0x0000c361
|
||||
|
||||
#define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069
|
||||
|
||||
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
|
||||
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
|
||||
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
|
||||
|
12
drivers/gpu/drm/nouveau/include/nvif/clb069.h
Normal file
12
drivers/gpu/drm/nouveau/include/nvif/clb069.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef __NVIF_CLB069_H__
|
||||
#define __NVIF_CLB069_H__
|
||||
struct nvif_clb069_v0 {
|
||||
__u8 version;
|
||||
__u8 pad01[3];
|
||||
__u32 entries;
|
||||
__u32 get;
|
||||
__u32 put;
|
||||
};
|
||||
|
||||
#define NVB069_V0_NTFY_FAULT 0x00
|
||||
#endif
|
@ -13,6 +13,8 @@ struct nvkm_fault {
|
||||
struct nvkm_event event;
|
||||
|
||||
struct nvkm_notify nrpfb;
|
||||
|
||||
struct nvkm_device_oclass user;
|
||||
};
|
||||
|
||||
struct nvkm_fault_data {
|
||||
|
@ -365,16 +365,15 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
|
||||
}
|
||||
|
||||
if (!sclass) {
|
||||
switch (index) {
|
||||
case 0: sclass = &nvkm_control_oclass; break;
|
||||
case 1:
|
||||
if (!device->mmu)
|
||||
return -EINVAL;
|
||||
if (index-- == 0)
|
||||
sclass = &nvkm_control_oclass;
|
||||
else if (device->mmu && index-- == 0)
|
||||
sclass = &device->mmu->user;
|
||||
break;
|
||||
default:
|
||||
else if (device->fault && index-- == 0)
|
||||
sclass = &device->fault->user;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
oclass->base = sclass->base;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
nvkm-y += nvkm/subdev/fault/base.o
|
||||
nvkm-y += nvkm/subdev/fault/user.o
|
||||
nvkm-y += nvkm/subdev/fault/gp100.o
|
||||
nvkm-y += nvkm/subdev/fault/gv100.o
|
||||
nvkm-y += nvkm/subdev/fault/tu102.o
|
||||
|
@ -176,5 +176,7 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device,
|
||||
return -ENOMEM;
|
||||
nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev);
|
||||
fault->func = func;
|
||||
fault->user.ctor = nvkm_ufault_new;
|
||||
fault->user.base = func->user.base;
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <subdev/mc.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static void
|
||||
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
|
||||
{
|
||||
@ -69,6 +71,7 @@ gp100_fault = {
|
||||
.buffer.init = gp100_fault_buffer_init,
|
||||
.buffer.fini = gp100_fault_buffer_fini,
|
||||
.buffer.intr = gp100_fault_buffer_intr,
|
||||
.user = { { 0, 0, MAXWELL_FAULT_BUFFER_A }, 0 },
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -34,7 +34,14 @@ struct nvkm_fault_func {
|
||||
void (*fini)(struct nvkm_fault_buffer *);
|
||||
void (*intr)(struct nvkm_fault_buffer *, bool enable);
|
||||
} buffer;
|
||||
struct {
|
||||
struct nvkm_sclass base;
|
||||
int rp;
|
||||
} user;
|
||||
};
|
||||
|
||||
int gv100_fault_oneinit(struct nvkm_fault *);
|
||||
|
||||
int nvkm_ufault_new(struct nvkm_device *, const struct nvkm_oclass *,
|
||||
void *, u32, struct nvkm_object **);
|
||||
#endif
|
||||
|
106
drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
Normal file
106
drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "priv.h"
|
||||
|
||||
#include <core/memory.h>
|
||||
#include <subdev/mmu.h>
|
||||
|
||||
#include <nvif/clb069.h>
|
||||
#include <nvif/unpack.h>
|
||||
|
||||
static int
|
||||
nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
|
||||
enum nvkm_object_map *type, u64 *addr, u64 *size)
|
||||
{
|
||||
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||
struct nvkm_device *device = buffer->fault->subdev.device;
|
||||
*type = NVKM_OBJECT_MAP_IO;
|
||||
*addr = device->func->resource_addr(device, 3) + buffer->addr;
|
||||
*size = nvkm_memory_size(buffer->mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_ufault_ntfy(struct nvkm_object *object, u32 type,
|
||||
struct nvkm_event **pevent)
|
||||
{
|
||||
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||
if (type == NVB069_V0_NTFY_FAULT) {
|
||||
*pevent = &buffer->fault->event;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_ufault_fini(struct nvkm_object *object, bool suspend)
|
||||
{
|
||||
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||
buffer->fault->func->buffer.fini(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_ufault_init(struct nvkm_object *object)
|
||||
{
|
||||
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||
buffer->fault->func->buffer.init(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
nvkm_ufault_dtor(struct nvkm_object *object)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct nvkm_object_func
|
||||
nvkm_ufault = {
|
||||
.dtor = nvkm_ufault_dtor,
|
||||
.init = nvkm_ufault_init,
|
||||
.fini = nvkm_ufault_fini,
|
||||
.ntfy = nvkm_ufault_ntfy,
|
||||
.map = nvkm_ufault_map,
|
||||
};
|
||||
|
||||
int
|
||||
nvkm_ufault_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
|
||||
void *argv, u32 argc, struct nvkm_object **pobject)
|
||||
{
|
||||
union {
|
||||
struct nvif_clb069_v0 v0;
|
||||
} *args = argv;
|
||||
struct nvkm_fault *fault = device->fault;
|
||||
struct nvkm_fault_buffer *buffer = fault->buffer[fault->func->user.rp];
|
||||
int ret = -ENOSYS;
|
||||
|
||||
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
|
||||
args->v0.entries = buffer->entries;
|
||||
args->v0.get = buffer->get;
|
||||
args->v0.put = buffer->put;
|
||||
} else
|
||||
return ret;
|
||||
|
||||
nvkm_object_ctor(&nvkm_ufault, oclass, &buffer->object);
|
||||
*pobject = &buffer->object;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user