diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/core/core/client.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/base.c | 163 | ||||
l--------- | drivers/gpu/drm/nouveau/core/include/nvif/class.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/class.h | 43 |
4 files changed, 171 insertions, 37 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index b30fe2014ecb..42016cde5781 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c @@ -26,6 +26,7 @@ #include <core/client.h> #include <core/handle.h> #include <core/option.h> +#include <nvif/class.h> #include <nvif/unpack.h> #include <nvif/event.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index ac31a6d685c3..c24fc604faee 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c @@ -26,9 +26,13 @@ #include <core/device.h> #include <core/client.h> #include <core/option.h> - +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/class.h> +#include <subdev/fb.h> +#include <subdev/instmem.h> + #include "priv.h" #include "acpi.h" @@ -53,11 +57,131 @@ nouveau_device_find(u64 name) /****************************************************************************** * nouveau_devobj (0x0080): class implementation *****************************************************************************/ + struct nouveau_devobj { struct nouveau_parent base; struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; }; +static int +nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size) +{ + struct nouveau_device *device = nv_device(object); + struct nouveau_fb *pfb = nouveau_fb(device); + struct nouveau_instmem *imem = nouveau_instmem(device); + union { + struct nv_device_info_v0 v0; + } *args = data; + int ret; + + nv_ioctl(object, "device info size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "device info vers %d\n", args->v0.version); + } else + return ret; + + switch (device->chipset) { + case 0x01a: + case 0x01f: + case 0x04c: + case 0x04e: + case 0x063: + case 0x067: + case 0x068: + case 0x0aa: + case 0x0ac: + case 0x0af: + args->v0.platform = NV_DEVICE_INFO_V0_IGP; + break; + default: + if (device->pdev) { + if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP)) + args->v0.platform = NV_DEVICE_INFO_V0_AGP; + else + if (pci_is_pcie(device->pdev)) + args->v0.platform = NV_DEVICE_INFO_V0_PCIE; + else + args->v0.platform = NV_DEVICE_INFO_V0_PCI; + } else { + args->v0.platform = NV_DEVICE_INFO_V0_SOC; + } + break; + } + + switch (device->card_type) { + case NV_04: args->v0.family = NV_DEVICE_INFO_V0_TNT; break; + case NV_10: + case NV_11: args->v0.family = NV_DEVICE_INFO_V0_CELSIUS; break; + case NV_20: args->v0.family = NV_DEVICE_INFO_V0_KELVIN; break; + case NV_30: args->v0.family = NV_DEVICE_INFO_V0_RANKINE; break; + case NV_40: args->v0.family = NV_DEVICE_INFO_V0_CURIE; break; + case NV_50: args->v0.family = NV_DEVICE_INFO_V0_TESLA; break; + case NV_C0: + case NV_D0: args->v0.family = NV_DEVICE_INFO_V0_FERMI; break; + case NV_E0: args->v0.family = NV_DEVICE_INFO_V0_KEPLER; break; + case GM100: args->v0.family = NV_DEVICE_INFO_V0_MAXWELL; break; + default: + args->v0.family = 0; + break; + } + + args->v0.chipset = device->chipset; + args->v0.revision = device->chipset >= 0x10 ? nv_rd32(device, 0) : 0x00; + if (pfb) args->v0.ram_size = args->v0.ram_user = pfb->ram->size; + else args->v0.ram_size = args->v0.ram_user = 0; + if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved; + return 0; +} + +static int +nouveau_devobj_mthd(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + switch (mthd) { + case NV_DEVICE_V0_INFO: + return nouveau_devobj_info(object, data, size); + default: + break; + } + return -EINVAL; +} + +static u8 +nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) +{ + return nv_rd08(object->engine, addr); +} + +static u16 +nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) +{ + return nv_rd16(object->engine, addr); +} + +static u32 +nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) +{ + return nv_rd32(object->engine, addr); +} + +static void +nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) +{ + nv_wr08(object->engine, addr, data); +} + +static void +nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) +{ + nv_wr16(object->engine, addr, data); +} + +static void +nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) +{ + nv_wr32(object->engine, addr, data); +} + static const u64 disable_map[] = { [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_DISABLE_VBIOS, [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_DISABLE_CORE, @@ -311,48 +435,13 @@ nouveau_devobj_dtor(struct nouveau_object *object) nouveau_parent_destroy(&devobj->base); } -static u8 -nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) -{ - return nv_rd08(object->engine, addr); -} - -static u16 -nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) -{ - return nv_rd16(object->engine, addr); -} - -static u32 -nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) -{ - return nv_rd32(object->engine, addr); -} - -static void -nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) -{ - nv_wr08(object->engine, addr, data); -} - -static void -nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) -{ - nv_wr16(object->engine, addr, data); -} - -static void -nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) -{ - nv_wr32(object->engine, addr, data); -} - static struct nouveau_ofuncs nouveau_devobj_ofuncs = { .ctor = nouveau_devobj_ctor, .dtor = nouveau_devobj_dtor, .init = _nouveau_parent_init, .fini = _nouveau_parent_fini, + .mthd = nouveau_devobj_mthd, .rd08 = nouveau_devobj_rd08, .rd16 = nouveau_devobj_rd16, .rd32 = nouveau_devobj_rd32, diff --git a/drivers/gpu/drm/nouveau/core/include/nvif/class.h b/drivers/gpu/drm/nouveau/core/include/nvif/class.h new file mode 120000 index 000000000000..f1ac4859edd4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/nvif/class.h @@ -0,0 +1 @@ +../../../nvif/class.h
\ No newline at end of file diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h new file mode 100644 index 000000000000..36ecc3e6a241 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/class.h @@ -0,0 +1,43 @@ +#ifndef __NVIF_CLASS_H__ +#define __NVIF_CLASS_H__ + +/******************************************************************************* + * class identifiers + ******************************************************************************/ + +/* the below match nvidia-assigned (either in hw, or sw) class numbers */ +#define NV_DEVICE 0x00000080 + + +/******************************************************************************* + * device + ******************************************************************************/ + +#define NV_DEVICE_V0_INFO 0x00 + +struct nv_device_info_v0 { + __u8 version; +#define NV_DEVICE_INFO_V0_IGP 0x00 +#define NV_DEVICE_INFO_V0_PCI 0x01 +#define NV_DEVICE_INFO_V0_AGP 0x02 +#define NV_DEVICE_INFO_V0_PCIE 0x03 +#define NV_DEVICE_INFO_V0_SOC 0x04 + __u8 platform; + __u16 chipset; /* from NV_PMC_BOOT_0 */ + __u8 revision; /* from NV_PMC_BOOT_0 */ +#define NV_DEVICE_INFO_V0_TNT 0x01 +#define NV_DEVICE_INFO_V0_CELSIUS 0x02 +#define NV_DEVICE_INFO_V0_KELVIN 0x03 +#define NV_DEVICE_INFO_V0_RANKINE 0x04 +#define NV_DEVICE_INFO_V0_CURIE 0x05 +#define NV_DEVICE_INFO_V0_TESLA 0x06 +#define NV_DEVICE_INFO_V0_FERMI 0x07 +#define NV_DEVICE_INFO_V0_KEPLER 0x08 +#define NV_DEVICE_INFO_V0_MAXWELL 0x09 + __u8 family; + __u8 pad06[2]; + __u64 ram_size; + __u64 ram_user; +}; + +#endif |