Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d01c3092 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/device: add method to retrieve some basic device info



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 8ec2a6ec
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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>
+126 −37
Original line number Diff line number Diff line
@@ -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,
+1 −0
Original line number Diff line number Diff line
../../../nvif/class.h
 No newline at end of file
+43 −0
Original line number Diff line number Diff line
#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