summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/include/core/device.h
blob: ac2881d1776ac1a071371a84f379ea57ea8ee856 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#ifndef __NOUVEAU_DEVICE_H__
#define __NOUVEAU_DEVICE_H__

#include <core/object.h>
#include <core/subdev.h>
#include <core/engine.h>

enum nv_subdev_type {
	NVDEV_ENGINE_DEVICE,
	NVDEV_SUBDEV_VBIOS,

	/* All subdevs from DEVINIT to DEVINIT_LAST will be created before
	 * *any* of them are initialised.  This subdev category is used
	 * for any subdevs that the VBIOS init table parsing may call out
	 * to during POST.
	 */
	NVDEV_SUBDEV_DEVINIT,
	NVDEV_SUBDEV_GPIO,
	NVDEV_SUBDEV_I2C,
	NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C,

	/* This grouping of subdevs are initialised right after they've
	 * been created, and are allowed to assume any subdevs in the
	 * list above them exist and have been initialised.
	 */
	NVDEV_SUBDEV_MXM,
	NVDEV_SUBDEV_MC,
	NVDEV_SUBDEV_BUS,
	NVDEV_SUBDEV_TIMER,
	NVDEV_SUBDEV_FB,
	NVDEV_SUBDEV_LTCG,
	NVDEV_SUBDEV_IBUS,
	NVDEV_SUBDEV_INSTMEM,
	NVDEV_SUBDEV_VM,
	NVDEV_SUBDEV_BAR,
	NVDEV_SUBDEV_PWR,
	NVDEV_SUBDEV_VOLT,
	NVDEV_SUBDEV_THERM,
	NVDEV_SUBDEV_CLOCK,

	NVDEV_ENGINE_DMAOBJ,
	NVDEV_ENGINE_FIFO,
	NVDEV_ENGINE_SW,
	NVDEV_ENGINE_GR,
	NVDEV_ENGINE_MPEG,
	NVDEV_ENGINE_ME,
	NVDEV_ENGINE_VP,
	NVDEV_ENGINE_CRYPT,
	NVDEV_ENGINE_BSP,
	NVDEV_ENGINE_PPP,
	NVDEV_ENGINE_COPY0,
	NVDEV_ENGINE_COPY1,
	NVDEV_ENGINE_COPY2,
	NVDEV_ENGINE_VIC,
	NVDEV_ENGINE_VENC,
	NVDEV_ENGINE_DISP,
	NVDEV_ENGINE_PERFMON,

	NVDEV_SUBDEV_NR,
};

struct nouveau_device {
	struct nouveau_engine base;
	struct list_head head;

	struct pci_dev *pdev;
	u64 handle;

	const char *cfgopt;
	const char *dbgopt;
	const char *name;
	const char *cname;

	enum {
		NV_04    = 0x04,
		NV_10    = 0x10,
		NV_11    = 0x11,
		NV_20    = 0x20,
		NV_30    = 0x30,
		NV_40    = 0x40,
		NV_50    = 0x50,
		NV_C0    = 0xc0,
		NV_D0    = 0xd0,
		NV_E0    = 0xe0,
	} card_type;
	u32 chipset;
	u32 crystal;

	struct nouveau_oclass *oclass[NVDEV_SUBDEV_NR];
	struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
};

static inline struct nouveau_device *
nv_device(void *obj)
{
	struct nouveau_object *object = nv_object(obj);
	struct nouveau_object *device = object;

	if (device->engine)
		device = device->engine;
	if (device->parent)
		device = device->parent;

#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
	if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) ||
		     (nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) {
		nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x",
			  nv_hclass(object), nv_hclass(device));
	}
#endif

	return (void *)device;
}

static inline struct nouveau_subdev *
nouveau_subdev(void *obj, int sub)
{
	if (nv_device(obj)->subdev[sub])
		return nv_subdev(nv_device(obj)->subdev[sub]);
	return NULL;
}

static inline struct nouveau_engine *
nouveau_engine(void *obj, int sub)
{
	struct nouveau_subdev *subdev = nouveau_subdev(obj, sub);
	if (subdev && nv_iclass(subdev, NV_ENGINE_CLASS))
		return nv_engine(subdev);
	return NULL;
}

static inline bool
nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub)
{
	struct nouveau_device *device = nv_device(object);
	return device->pdev->device == dev &&
	       device->pdev->subsystem_vendor == ven &&
	       device->pdev->subsystem_device == sub;
}

#endif