summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/include
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
commit57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch)
tree5e910f0e82173f4ef4f51111366a3f1299037a7b /drivers/gpu/drm/nouveau/include
Initial import
Diffstat (limited to 'drivers/gpu/drm/nouveau/include')
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/class.h583
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/client.h39
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/device.h61
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/driver.h22
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/event.h62
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/ioctl.h128
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/list.h353
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/notify.h39
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/object.h75
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/os.h44
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/unpack.h24
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/client.h55
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/debug.h18
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/device.h101
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h62
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h51
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/engine.h56
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/enum.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/event.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h64
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/handle.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h7
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/mm.h40
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h53
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/notify.h38
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/object.h203
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/option.h17
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/os.h4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/parent.h58
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/printk.h29
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h20
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h119
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h16
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/device.h30
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h26
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h81
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h127
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h88
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h62
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h7
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h7
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h50
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h35
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h33
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h29
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h29
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h27
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h11
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h37
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h27
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h44
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h26
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h65
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h39
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h31
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h25
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h46
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h25
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h11
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h20
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h16
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h41
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h75
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h35
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h141
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h72
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h11
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h23
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h18
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h50
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h161
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h154
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h28
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h44
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h135
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h49
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h31
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h28
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h104
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h54
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h79
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h61
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h30
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h58
101 files changed, 5373 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h
new file mode 100644
index 000000000..64f8b2f68
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/class.h
@@ -0,0 +1,583 @@
+#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
+
+#define NV_DMA_FROM_MEMORY 0x00000002
+#define NV_DMA_TO_MEMORY 0x00000003
+#define NV_DMA_IN_MEMORY 0x0000003d
+
+#define FERMI_TWOD_A 0x0000902d
+
+#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x00009039
+
+#define KEPLER_INLINE_TO_MEMORY_A 0x0000a040
+#define KEPLER_INLINE_TO_MEMORY_B 0x0000a140
+
+#define NV04_DISP 0x00000046
+
+#define NV03_CHANNEL_DMA 0x0000006b
+#define NV10_CHANNEL_DMA 0x0000006e
+#define NV17_CHANNEL_DMA 0x0000176e
+#define NV40_CHANNEL_DMA 0x0000406e
+#define NV50_CHANNEL_DMA 0x0000506e
+#define G82_CHANNEL_DMA 0x0000826e
+
+#define NV50_CHANNEL_GPFIFO 0x0000506f
+#define G82_CHANNEL_GPFIFO 0x0000826f
+#define FERMI_CHANNEL_GPFIFO 0x0000906f
+#define KEPLER_CHANNEL_GPFIFO_A 0x0000a06f
+#define MAXWELL_CHANNEL_GPFIFO_A 0x0000b06f
+
+#define NV50_DISP 0x00005070
+#define G82_DISP 0x00008270
+#define GT200_DISP 0x00008370
+#define GT214_DISP 0x00008570
+#define GT206_DISP 0x00008870
+#define GF110_DISP 0x00009070
+#define GK104_DISP 0x00009170
+#define GK110_DISP 0x00009270
+#define GM107_DISP 0x00009470
+#define GM204_DISP 0x00009570
+
+#define NV50_DISP_CURSOR 0x0000507a
+#define G82_DISP_CURSOR 0x0000827a
+#define GT214_DISP_CURSOR 0x0000857a
+#define GF110_DISP_CURSOR 0x0000907a
+#define GK104_DISP_CURSOR 0x0000917a
+
+#define NV50_DISP_OVERLAY 0x0000507b
+#define G82_DISP_OVERLAY 0x0000827b
+#define GT214_DISP_OVERLAY 0x0000857b
+#define GF110_DISP_OVERLAY 0x0000907b
+#define GK104_DISP_OVERLAY 0x0000917b
+
+#define NV50_DISP_BASE_CHANNEL_DMA 0x0000507c
+#define G82_DISP_BASE_CHANNEL_DMA 0x0000827c
+#define GT200_DISP_BASE_CHANNEL_DMA 0x0000837c
+#define GT214_DISP_BASE_CHANNEL_DMA 0x0000857c
+#define GF110_DISP_BASE_CHANNEL_DMA 0x0000907c
+#define GK104_DISP_BASE_CHANNEL_DMA 0x0000917c
+#define GK110_DISP_BASE_CHANNEL_DMA 0x0000927c
+
+#define NV50_DISP_CORE_CHANNEL_DMA 0x0000507d
+#define G82_DISP_CORE_CHANNEL_DMA 0x0000827d
+#define GT200_DISP_CORE_CHANNEL_DMA 0x0000837d
+#define GT214_DISP_CORE_CHANNEL_DMA 0x0000857d
+#define GT206_DISP_CORE_CHANNEL_DMA 0x0000887d
+#define GF110_DISP_CORE_CHANNEL_DMA 0x0000907d
+#define GK104_DISP_CORE_CHANNEL_DMA 0x0000917d
+#define GK110_DISP_CORE_CHANNEL_DMA 0x0000927d
+#define GM107_DISP_CORE_CHANNEL_DMA 0x0000947d
+#define GM204_DISP_CORE_CHANNEL_DMA 0x0000957d
+
+#define NV50_DISP_OVERLAY_CHANNEL_DMA 0x0000507e
+#define G82_DISP_OVERLAY_CHANNEL_DMA 0x0000827e
+#define GT200_DISP_OVERLAY_CHANNEL_DMA 0x0000837e
+#define GT214_DISP_OVERLAY_CHANNEL_DMA 0x0000857e
+#define GF110_DISP_OVERLAY_CONTROL_DMA 0x0000907e
+#define GK104_DISP_OVERLAY_CONTROL_DMA 0x0000917e
+
+#define FERMI_A 0x00009097
+#define FERMI_B 0x00009197
+#define FERMI_C 0x00009297
+
+#define KEPLER_A 0x0000a097
+#define KEPLER_B 0x0000a197
+#define KEPLER_C 0x0000a297
+
+#define MAXWELL_A 0x0000b097
+#define MAXWELL_B 0x0000b197
+
+#define FERMI_COMPUTE_A 0x000090c0
+#define FERMI_COMPUTE_B 0x000091c0
+
+#define KEPLER_COMPUTE_A 0x0000a0c0
+#define KEPLER_COMPUTE_B 0x0000a1c0
+
+#define MAXWELL_COMPUTE_A 0x0000b0c0
+#define MAXWELL_COMPUTE_B 0x0000b1c0
+
+
+/*******************************************************************************
+ * client
+ ******************************************************************************/
+
+#define NV_CLIENT_DEVLIST 0x00
+
+struct nv_client_devlist_v0 {
+ __u8 version;
+ __u8 count;
+ __u8 pad02[6];
+ __u64 device[];
+};
+
+
+/*******************************************************************************
+ * device
+ ******************************************************************************/
+
+struct nv_device_v0 {
+ __u8 version;
+ __u8 pad01[7];
+ __u64 device; /* device identifier, ~0 for client default */
+#define NV_DEVICE_V0_DISABLE_IDENTIFY 0x0000000000000001ULL
+#define NV_DEVICE_V0_DISABLE_MMIO 0x0000000000000002ULL
+#define NV_DEVICE_V0_DISABLE_VBIOS 0x0000000000000004ULL
+#define NV_DEVICE_V0_DISABLE_CORE 0x0000000000000008ULL
+#define NV_DEVICE_V0_DISABLE_DISP 0x0000000000010000ULL
+#define NV_DEVICE_V0_DISABLE_FIFO 0x0000000000020000ULL
+#define NV_DEVICE_V0_DISABLE_GR 0x0000000100000000ULL
+#define NV_DEVICE_V0_DISABLE_MPEG 0x0000000200000000ULL
+#define NV_DEVICE_V0_DISABLE_ME 0x0000000400000000ULL
+#define NV_DEVICE_V0_DISABLE_VP 0x0000000800000000ULL
+#define NV_DEVICE_V0_DISABLE_CIPHER 0x0000001000000000ULL
+#define NV_DEVICE_V0_DISABLE_BSP 0x0000002000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSPPP 0x0000004000000000ULL
+#define NV_DEVICE_V0_DISABLE_CE0 0x0000008000000000ULL
+#define NV_DEVICE_V0_DISABLE_CE1 0x0000010000000000ULL
+#define NV_DEVICE_V0_DISABLE_VIC 0x0000020000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSENC 0x0000040000000000ULL
+#define NV_DEVICE_V0_DISABLE_CE2 0x0000080000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSVLD 0x0000100000000000ULL
+#define NV_DEVICE_V0_DISABLE_SEC 0x0000200000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSPDEC 0x0000400000000000ULL
+ __u64 disable; /* disable particular subsystems */
+ __u64 debug0; /* as above, but *internal* ids, and *NOT* ABI */
+};
+
+#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;
+};
+
+
+/*******************************************************************************
+ * context dma
+ ******************************************************************************/
+
+struct nv_dma_v0 {
+ __u8 version;
+#define NV_DMA_V0_TARGET_VM 0x00
+#define NV_DMA_V0_TARGET_VRAM 0x01
+#define NV_DMA_V0_TARGET_PCI 0x02
+#define NV_DMA_V0_TARGET_PCI_US 0x03
+#define NV_DMA_V0_TARGET_AGP 0x04
+ __u8 target;
+#define NV_DMA_V0_ACCESS_VM 0x00
+#define NV_DMA_V0_ACCESS_RD 0x01
+#define NV_DMA_V0_ACCESS_WR 0x02
+#define NV_DMA_V0_ACCESS_RDWR (NV_DMA_V0_ACCESS_RD | NV_DMA_V0_ACCESS_WR)
+ __u8 access;
+ __u8 pad03[5];
+ __u64 start;
+ __u64 limit;
+ /* ... chipset-specific class data */
+};
+
+struct nv50_dma_v0 {
+ __u8 version;
+#define NV50_DMA_V0_PRIV_VM 0x00
+#define NV50_DMA_V0_PRIV_US 0x01
+#define NV50_DMA_V0_PRIV__S 0x02
+ __u8 priv;
+#define NV50_DMA_V0_PART_VM 0x00
+#define NV50_DMA_V0_PART_256 0x01
+#define NV50_DMA_V0_PART_1KB 0x02
+ __u8 part;
+#define NV50_DMA_V0_COMP_NONE 0x00
+#define NV50_DMA_V0_COMP_1 0x01
+#define NV50_DMA_V0_COMP_2 0x02
+#define NV50_DMA_V0_COMP_VM 0x03
+ __u8 comp;
+#define NV50_DMA_V0_KIND_PITCH 0x00
+#define NV50_DMA_V0_KIND_VM 0x7f
+ __u8 kind;
+ __u8 pad05[3];
+};
+
+struct gf100_dma_v0 {
+ __u8 version;
+#define GF100_DMA_V0_PRIV_VM 0x00
+#define GF100_DMA_V0_PRIV_US 0x01
+#define GF100_DMA_V0_PRIV__S 0x02
+ __u8 priv;
+#define GF100_DMA_V0_KIND_PITCH 0x00
+#define GF100_DMA_V0_KIND_VM 0xff
+ __u8 kind;
+ __u8 pad03[5];
+};
+
+struct gf110_dma_v0 {
+ __u8 version;
+#define GF110_DMA_V0_PAGE_LP 0x00
+#define GF110_DMA_V0_PAGE_SP 0x01
+ __u8 page;
+#define GF110_DMA_V0_KIND_PITCH 0x00
+#define GF110_DMA_V0_KIND_VM 0xff
+ __u8 kind;
+ __u8 pad03[5];
+};
+
+
+/*******************************************************************************
+ * perfmon
+ ******************************************************************************/
+
+struct nvif_perfctr_v0 {
+ __u8 version;
+ __u8 pad01[1];
+ __u16 logic_op;
+ __u8 pad04[4];
+ char name[4][64];
+};
+
+#define NVIF_PERFCTR_V0_QUERY 0x00
+#define NVIF_PERFCTR_V0_SAMPLE 0x01
+#define NVIF_PERFCTR_V0_READ 0x02
+
+struct nvif_perfctr_query_v0 {
+ __u8 version;
+ __u8 pad01[3];
+ __u32 iter;
+ char name[64];
+};
+
+struct nvif_perfctr_sample {
+};
+
+struct nvif_perfctr_read_v0 {
+ __u8 version;
+ __u8 pad01[7];
+ __u32 ctr;
+ __u32 clk;
+};
+
+
+/*******************************************************************************
+ * device control
+ ******************************************************************************/
+
+#define NVIF_CONTROL_PSTATE_INFO 0x00
+#define NVIF_CONTROL_PSTATE_ATTR 0x01
+#define NVIF_CONTROL_PSTATE_USER 0x02
+
+struct nvif_control_pstate_info_v0 {
+ __u8 version;
+ __u8 count; /* out: number of power states */
+#define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE (-1)
+#define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_PERFMON (-2)
+ __s8 ustate_ac; /* out: target pstate index */
+ __s8 ustate_dc; /* out: target pstate index */
+ __s8 pwrsrc; /* out: current power source */
+#define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN (-1)
+#define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_PERFMON (-2)
+ __s8 pstate; /* out: current pstate index */
+ __u8 pad06[2];
+};
+
+struct nvif_control_pstate_attr_v0 {
+ __u8 version;
+#define NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT (-1)
+ __s8 state; /* in: index of pstate to query
+ * out: pstate identifier
+ */
+ __u8 index; /* in: index of attribute to query
+ * out: index of next attribute, or 0 if no more
+ */
+ __u8 pad03[5];
+ __u32 min;
+ __u32 max;
+ char name[32];
+ char unit[16];
+};
+
+struct nvif_control_pstate_user_v0 {
+ __u8 version;
+#define NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN (-1)
+#define NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON (-2)
+ __s8 ustate; /* in: pstate identifier */
+ __s8 pwrsrc; /* in: target power source */
+ __u8 pad03[5];
+};
+
+
+/*******************************************************************************
+ * DMA FIFO channels
+ ******************************************************************************/
+
+struct nv03_channel_dma_v0 {
+ __u8 version;
+ __u8 chid;
+ __u8 pad02[2];
+ __u32 pushbuf;
+ __u64 offset;
+};
+
+#define G82_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
+
+/*******************************************************************************
+ * GPFIFO channels
+ ******************************************************************************/
+
+struct nv50_channel_gpfifo_v0 {
+ __u8 version;
+ __u8 chid;
+ __u8 pad01[6];
+ __u32 pushbuf;
+ __u32 ilength;
+ __u64 ioffset;
+};
+
+struct kepler_channel_gpfifo_a_v0 {
+ __u8 version;
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR 0x01
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPDEC 0x02
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPPP 0x04
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSVLD 0x08
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0 0x10
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1 0x20
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
+ __u8 engine;
+ __u16 chid;
+ __u8 pad04[4];
+ __u32 pushbuf;
+ __u32 ilength;
+ __u64 ioffset;
+};
+
+/*******************************************************************************
+ * legacy display
+ ******************************************************************************/
+
+#define NV04_DISP_NTFY_VBLANK 0x00
+#define NV04_DISP_NTFY_CONN 0x01
+
+struct nv04_disp_mthd_v0 {
+ __u8 version;
+#define NV04_DISP_SCANOUTPOS 0x00
+ __u8 method;
+ __u8 head;
+ __u8 pad03[5];
+};
+
+struct nv04_disp_scanoutpos_v0 {
+ __u8 version;
+ __u8 pad01[7];
+ __s64 time[2];
+ __u16 vblanks;
+ __u16 vblanke;
+ __u16 vtotal;
+ __u16 vline;
+ __u16 hblanks;
+ __u16 hblanke;
+ __u16 htotal;
+ __u16 hline;
+};
+
+/*******************************************************************************
+ * display
+ ******************************************************************************/
+
+#define NV50_DISP_MTHD 0x00
+
+struct nv50_disp_mthd_v0 {
+ __u8 version;
+#define NV50_DISP_SCANOUTPOS 0x00
+ __u8 method;
+ __u8 head;
+ __u8 pad03[5];
+};
+
+struct nv50_disp_mthd_v1 {
+ __u8 version;
+#define NV50_DISP_MTHD_V1_DAC_PWR 0x10
+#define NV50_DISP_MTHD_V1_DAC_LOAD 0x11
+#define NV50_DISP_MTHD_V1_SOR_PWR 0x20
+#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
+#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
+#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23
+#define NV50_DISP_MTHD_V1_SOR_DP_PWR 0x24
+#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
+ __u8 method;
+ __u16 hasht;
+ __u16 hashm;
+ __u8 pad06[2];
+};
+
+struct nv50_disp_dac_pwr_v0 {
+ __u8 version;
+ __u8 state;
+ __u8 data;
+ __u8 vsync;
+ __u8 hsync;
+ __u8 pad05[3];
+};
+
+struct nv50_disp_dac_load_v0 {
+ __u8 version;
+ __u8 load;
+ __u8 pad02[2];
+ __u32 data;
+};
+
+struct nv50_disp_sor_pwr_v0 {
+ __u8 version;
+ __u8 state;
+ __u8 pad02[6];
+};
+
+struct nv50_disp_sor_hda_eld_v0 {
+ __u8 version;
+ __u8 pad01[7];
+ __u8 data[];
+};
+
+struct nv50_disp_sor_hdmi_pwr_v0 {
+ __u8 version;
+ __u8 state;
+ __u8 max_ac_packet;
+ __u8 rekey;
+ __u8 pad04[4];
+};
+
+struct nv50_disp_sor_lvds_script_v0 {
+ __u8 version;
+ __u8 pad01[1];
+ __u16 script;
+ __u8 pad04[4];
+};
+
+struct nv50_disp_sor_dp_pwr_v0 {
+ __u8 version;
+ __u8 state;
+ __u8 pad02[6];
+};
+
+struct nv50_disp_pior_pwr_v0 {
+ __u8 version;
+ __u8 state;
+ __u8 type;
+ __u8 pad03[5];
+};
+
+/* core */
+struct nv50_disp_core_channel_dma_v0 {
+ __u8 version;
+ __u8 pad01[3];
+ __u32 pushbuf;
+};
+
+#define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
+
+/* cursor immediate */
+struct nv50_disp_cursor_v0 {
+ __u8 version;
+ __u8 head;
+ __u8 pad02[6];
+};
+
+#define NV50_DISP_CURSOR_V0_NTFY_UEVENT 0x00
+
+/* base */
+struct nv50_disp_base_channel_dma_v0 {
+ __u8 version;
+ __u8 pad01[2];
+ __u8 head;
+ __u32 pushbuf;
+};
+
+#define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
+
+/* overlay */
+struct nv50_disp_overlay_channel_dma_v0 {
+ __u8 version;
+ __u8 pad01[2];
+ __u8 head;
+ __u32 pushbuf;
+};
+
+#define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
+
+/* overlay immediate */
+struct nv50_disp_overlay_v0 {
+ __u8 version;
+ __u8 head;
+ __u8 pad02[6];
+};
+
+#define NV50_DISP_OVERLAY_V0_NTFY_UEVENT 0x00
+
+/*******************************************************************************
+ * fermi
+ ******************************************************************************/
+
+#define FERMI_A_ZBC_COLOR 0x00
+#define FERMI_A_ZBC_DEPTH 0x01
+
+struct fermi_a_zbc_color_v0 {
+ __u8 version;
+#define FERMI_A_ZBC_COLOR_V0_FMT_ZERO 0x01
+#define FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE 0x02
+#define FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32 0x04
+#define FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16 0x08
+#define FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16 0x0c
+#define FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16 0x10
+#define FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16 0x14
+#define FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16 0x16
+#define FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8 0x18
+#define FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8 0x1c
+#define FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10 0x20
+#define FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10 0x24
+#define FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8 0x28
+#define FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8 0x2c
+#define FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8 0x30
+#define FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8 0x34
+#define FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8 0x38
+#define FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10 0x3c
+#define FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11 0x40
+ __u8 format;
+ __u8 index;
+ __u8 pad03[5];
+ __u32 ds[4];
+ __u32 l2[4];
+};
+
+struct fermi_a_zbc_depth_v0 {
+ __u8 version;
+#define FERMI_A_ZBC_DEPTH_V0_FMT_FP32 0x01
+ __u8 format;
+ __u8 index;
+ __u8 pad03[5];
+ __u32 ds;
+ __u32 l2;
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/client.h b/drivers/gpu/drm/nouveau/include/nvif/client.h
new file mode 100644
index 000000000..eca648ef0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/client.h
@@ -0,0 +1,39 @@
+#ifndef __NVIF_CLIENT_H__
+#define __NVIF_CLIENT_H__
+
+#include <nvif/object.h>
+
+struct nvif_client {
+ struct nvif_object base;
+ struct nvif_object *object; /*XXX: hack for nvif_object() */
+ const struct nvif_driver *driver;
+ bool super;
+};
+
+static inline struct nvif_client *
+nvif_client(struct nvif_object *object)
+{
+ while (object && object->parent != object)
+ object = object->parent;
+ return (void *)object;
+}
+
+int nvif_client_init(void (*dtor)(struct nvif_client *), const char *,
+ const char *, u64, const char *, const char *,
+ struct nvif_client *);
+void nvif_client_fini(struct nvif_client *);
+int nvif_client_new(const char *, const char *, u64, const char *,
+ const char *, struct nvif_client **);
+void nvif_client_ref(struct nvif_client *, struct nvif_client **);
+int nvif_client_ioctl(struct nvif_client *, void *, u32);
+int nvif_client_suspend(struct nvif_client *);
+int nvif_client_resume(struct nvif_client *);
+
+/*XXX*/
+#include <core/client.h>
+#define nvxx_client(a) ({ \
+ struct nvif_client *_client = nvif_client(nvif_object(a)); \
+ nvkm_client(_client->base.priv); \
+})
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h
new file mode 100644
index 000000000..88553a741
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/device.h
@@ -0,0 +1,61 @@
+#ifndef __NVIF_DEVICE_H__
+#define __NVIF_DEVICE_H__
+
+#include <nvif/object.h>
+#include <nvif/class.h>
+
+struct nvif_device {
+ struct nvif_object base;
+ struct nvif_object *object; /*XXX: hack for nvif_object() */
+ struct nv_device_info_v0 info;
+};
+
+static inline struct nvif_device *
+nvif_device(struct nvif_object *object)
+{
+ while (object && object->oclass != 0x0080 /*XXX: NV_DEVICE_CLASS*/ )
+ object = object->parent;
+ return (void *)object;
+}
+
+int nvif_device_init(struct nvif_object *, void (*dtor)(struct nvif_device *),
+ u32 handle, u32 oclass, void *, u32,
+ struct nvif_device *);
+void nvif_device_fini(struct nvif_device *);
+int nvif_device_new(struct nvif_object *, u32 handle, u32 oclass,
+ void *, u32, struct nvif_device **);
+void nvif_device_ref(struct nvif_device *, struct nvif_device **);
+
+/*XXX*/
+#include <subdev/bios.h>
+#include <subdev/fb.h>
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
+#include <subdev/gpio.h>
+#include <subdev/clk.h>
+#include <subdev/i2c.h>
+#include <subdev/timer.h>
+#include <subdev/therm.h>
+
+#define nvxx_device(a) nv_device(nvxx_object((a)))
+#define nvxx_bios(a) nvkm_bios(nvxx_device(a))
+#define nvxx_fb(a) nvkm_fb(nvxx_device(a))
+#define nvxx_mmu(a) nvkm_mmu(nvxx_device(a))
+#define nvxx_bar(a) nvkm_bar(nvxx_device(a))
+#define nvxx_gpio(a) nvkm_gpio(nvxx_device(a))
+#define nvxx_clk(a) nvkm_clk(nvxx_device(a))
+#define nvxx_i2c(a) nvkm_i2c(nvxx_device(a))
+#define nvxx_timer(a) nvkm_timer(nvxx_device(a))
+#define nvxx_wait(a,b,c,d) nv_wait(nvxx_timer(a), (b), (c), (d))
+#define nvxx_wait_cb(a,b,c) nv_wait_cb(nvxx_timer(a), (b), (c))
+#define nvxx_therm(a) nvkm_therm(nvxx_device(a))
+
+#include <core/device.h>
+#include <engine/fifo.h>
+#include <engine/gr.h>
+#include <engine/sw.h>
+
+#define nvxx_fifo(a) nvkm_fifo(nvxx_device(a))
+#define nvxx_fifo_chan(a) ((struct nvkm_fifo_chan *)nvxx_object(a))
+#define nvxx_gr(a) ((struct nvkm_gr *)nvkm_engine(nvxx_object(a), NVDEV_ENGINE_GR))
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driver.h b/drivers/gpu/drm/nouveau/include/nvif/driver.h
new file mode 100644
index 000000000..8bd39e692
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/driver.h
@@ -0,0 +1,22 @@
+#ifndef __NVIF_DRIVER_H__
+#define __NVIF_DRIVER_H__
+
+struct nvif_driver {
+ const char *name;
+ int (*init)(const char *name, u64 device, const char *cfg,
+ const char *dbg, void **priv);
+ void (*fini)(void *priv);
+ int (*suspend)(void *priv);
+ int (*resume)(void *priv);
+ int (*ioctl)(void *priv, bool super, void *data, u32 size, void **hack);
+ void __iomem *(*map)(void *priv, u64 handle, u32 size);
+ void (*unmap)(void *priv, void __iomem *ptr, u32 size);
+ bool keep;
+};
+
+extern const struct nvif_driver nvif_driver_nvkm;
+extern const struct nvif_driver nvif_driver_drm;
+extern const struct nvif_driver nvif_driver_lib;
+extern const struct nvif_driver nvif_driver_null;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/event.h b/drivers/gpu/drm/nouveau/include/nvif/event.h
new file mode 100644
index 000000000..21764499b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/event.h
@@ -0,0 +1,62 @@
+#ifndef __NVIF_EVENT_H__
+#define __NVIF_EVENT_H__
+
+struct nvif_notify_req_v0 {
+ __u8 version;
+ __u8 reply;
+ __u8 pad02[5];
+#define NVIF_NOTIFY_V0_ROUTE_NVIF 0x00
+ __u8 route;
+ __u64 token; /* must be unique */
+ __u8 data[]; /* request data (below) */
+};
+
+struct nvif_notify_rep_v0 {
+ __u8 version;
+ __u8 pad01[6];
+ __u8 route;
+ __u64 token;
+ __u8 data[]; /* reply data (below) */
+};
+
+struct nvif_notify_head_req_v0 {
+ /* nvif_notify_req ... */
+ __u8 version;
+ __u8 head;
+ __u8 pad02[6];
+};
+
+struct nvif_notify_head_rep_v0 {
+ /* nvif_notify_rep ... */
+ __u8 version;
+ __u8 pad01[7];
+};
+
+struct nvif_notify_conn_req_v0 {
+ /* nvif_notify_req ... */
+ __u8 version;
+#define NVIF_NOTIFY_CONN_V0_PLUG 0x01
+#define NVIF_NOTIFY_CONN_V0_UNPLUG 0x02
+#define NVIF_NOTIFY_CONN_V0_IRQ 0x04
+#define NVIF_NOTIFY_CONN_V0_ANY 0x07
+ __u8 mask;
+ __u8 conn;
+ __u8 pad03[5];
+};
+
+struct nvif_notify_conn_rep_v0 {
+ /* nvif_notify_rep ... */
+ __u8 version;
+ __u8 mask;
+ __u8 pad02[6];
+};
+
+struct nvif_notify_uevent_req {
+ /* nvif_notify_req ... */
+};
+
+struct nvif_notify_uevent_rep {
+ /* nvif_notify_rep ... */
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/ioctl.h b/drivers/gpu/drm/nouveau/include/nvif/ioctl.h
new file mode 100644
index 000000000..4cd8e323b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/ioctl.h
@@ -0,0 +1,128 @@
+#ifndef __NVIF_IOCTL_H__
+#define __NVIF_IOCTL_H__
+
+struct nvif_ioctl_v0 {
+ __u8 version;
+#define NVIF_IOCTL_V0_OWNER_NVIF 0x00
+#define NVIF_IOCTL_V0_OWNER_ANY 0xff
+ __u8 owner;
+#define NVIF_IOCTL_V0_NOP 0x00
+#define NVIF_IOCTL_V0_SCLASS 0x01
+#define NVIF_IOCTL_V0_NEW 0x02
+#define NVIF_IOCTL_V0_DEL 0x03
+#define NVIF_IOCTL_V0_MTHD 0x04
+#define NVIF_IOCTL_V0_RD 0x05
+#define NVIF_IOCTL_V0_WR 0x06
+#define NVIF_IOCTL_V0_MAP 0x07
+#define NVIF_IOCTL_V0_UNMAP 0x08
+#define NVIF_IOCTL_V0_NTFY_NEW 0x09
+#define NVIF_IOCTL_V0_NTFY_DEL 0x0a
+#define NVIF_IOCTL_V0_NTFY_GET 0x0b
+#define NVIF_IOCTL_V0_NTFY_PUT 0x0c
+ __u8 type;
+ __u8 path_nr;
+#define NVIF_IOCTL_V0_ROUTE_NVIF 0x00
+#define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff
+ __u8 pad04[3];
+ __u8 route;
+ __u64 token;
+ __u32 path[8]; /* in reverse */
+ __u8 data[]; /* ioctl data (below) */
+};
+
+struct nvif_ioctl_nop {
+};
+
+struct nvif_ioctl_sclass_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 count;
+ __u8 pad02[6];
+ __u32 oclass[];
+};
+
+struct nvif_ioctl_new_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 pad01[6];
+ __u8 route;
+ __u64 token;
+ __u32 handle;
+/* these class numbers are made up by us, and not nvidia-assigned */
+#define NVIF_IOCTL_NEW_V0_PERFCTR 0x0000ffff
+#define NVIF_IOCTL_NEW_V0_CONTROL 0x0000fffe
+ __u32 oclass;
+ __u8 data[]; /* class data (class.h) */
+};
+
+struct nvif_ioctl_del {
+};
+
+struct nvif_ioctl_rd_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 size;
+ __u8 pad02[2];
+ __u32 data;
+ __u64 addr;
+};
+
+struct nvif_ioctl_wr_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 size;
+ __u8 pad02[2];
+ __u32 data;
+ __u64 addr;
+};
+
+struct nvif_ioctl_map_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 pad01[3];
+ __u32 length;
+ __u64 handle;
+};
+
+struct nvif_ioctl_unmap {
+};
+
+struct nvif_ioctl_ntfy_new_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 event;
+ __u8 index;
+ __u8 pad03[5];
+ __u8 data[]; /* event request data (event.h) */
+};
+
+struct nvif_ioctl_ntfy_del_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 index;
+ __u8 pad02[6];
+};
+
+struct nvif_ioctl_ntfy_get_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 index;
+ __u8 pad02[6];
+};
+
+struct nvif_ioctl_ntfy_put_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 index;
+ __u8 pad02[6];
+};
+
+struct nvif_ioctl_mthd_v0 {
+ /* nvif_ioctl ... */
+ __u8 version;
+ __u8 method;
+ __u8 pad02[6];
+ __u8 data[]; /* method data (class.h) */
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/list.h b/drivers/gpu/drm/nouveau/include/nvif/list.h
new file mode 100644
index 000000000..8af5d144e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/list.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ */
+
+/* Modified by Ben Skeggs <bskeggs@redhat.com> to match kernel list APIs */
+
+#ifndef _XORG_LIST_H_
+#define _XORG_LIST_H_
+
+/**
+ * @file Classic doubly-link circular list implementation.
+ * For real usage examples of the linked list, see the file test/list.c
+ *
+ * Example:
+ * We need to keep a list of struct foo in the parent struct bar, i.e. what
+ * we want is something like this.
+ *
+ * struct bar {
+ * ...
+ * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
+ * ...
+ * }
+ *
+ * We need one list head in bar and a list element in all list_of_foos (both are of
+ * data type 'struct list_head').
+ *
+ * struct bar {
+ * ...
+ * struct list_head list_of_foos;
+ * ...
+ * }
+ *
+ * struct foo {
+ * ...
+ * struct list_head entry;
+ * ...
+ * }
+ *
+ * Now we initialize the list head:
+ *
+ * struct bar bar;
+ * ...
+ * INIT_LIST_HEAD(&bar.list_of_foos);
+ *
+ * Then we create the first element and add it to this list:
+ *
+ * struct foo *foo = malloc(...);
+ * ....
+ * list_add(&foo->entry, &bar.list_of_foos);
+ *
+ * Repeat the above for each element you want to add to the list. Deleting
+ * works with the element itself.
+ * list_del(&foo->entry);
+ * free(foo);
+ *
+ * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
+ * list again.
+ *
+ * Looping through the list requires a 'struct foo' as iterator and the
+ * name of the field the subnodes use.
+ *
+ * struct foo *iterator;
+ * list_for_each_entry(iterator, &bar.list_of_foos, entry) {
+ * if (iterator->something == ...)
+ * ...
+ * }
+ *
+ * Note: You must not call list_del() on the iterator if you continue the
+ * loop. You need to run the safe for-each loop instead:
+ *
+ * struct foo *iterator, *next;
+ * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
+ * if (...)
+ * list_del(&iterator->entry);
+ * }
+ *
+ */
+
+/**
+ * The linkage struct for list nodes. This struct must be part of your
+ * to-be-linked struct. struct list_head is required for both the head of the
+ * list and for each list node.
+ *
+ * Position and name of the struct list_head field is irrelevant.
+ * There are no requirements that elements of a list are of the same type.
+ * There are no requirements for a list head, any struct list_head can be a list
+ * head.
+ */
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+/**
+ * Initialize the list as an empty list.
+ *
+ * Example:
+ * INIT_LIST_HEAD(&bar->list_of_foos);
+ *
+ * @param The list to initialized.
+ */
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void
+INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list->prev = list;
+}
+
+static inline void
+__list_add(struct list_head *entry,
+ struct list_head *prev, struct list_head *next)
+{
+ next->prev = entry;
+ entry->next = next;
+ entry->prev = prev;
+ prev->next = entry;
+}
+
+/**
+ * Insert a new element after the given list head. The new element does not
+ * need to be initialised as empty list.
+ * The list changes from:
+ * head → some element → ...
+ * to
+ * head → new element → older element → ...
+ *
+ * Example:
+ * struct foo *newfoo = malloc(...);
+ * list_add(&newfoo->entry, &bar->list_of_foos);
+ *
+ * @param entry The new element to prepend to the list.
+ * @param head The existing list.
+ */
+static inline void
+list_add(struct list_head *entry, struct list_head *head)
+{
+ __list_add(entry, head, head->next);
+}
+
+/**
+ * Append a new element to the end of the list given with this list head.
+ *
+ * The list changes from:
+ * head → some element → ... → lastelement
+ * to
+ * head → some element → ... → lastelement → new element
+ *
+ * Example:
+ * struct foo *newfoo = malloc(...);
+ * list_add_tail(&newfoo->entry, &bar->list_of_foos);
+ *
+ * @param entry The new element to prepend to the list.
+ * @param head The existing list.
+ */
+static inline void
+list_add_tail(struct list_head *entry, struct list_head *head)
+{
+ __list_add(entry, head->prev, head);
+}
+
+static inline void
+__list_del(struct list_head *prev, struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * Remove the element from the list it is in. Using this function will reset
+ * the pointers to/from this element so it is removed from the list. It does
+ * NOT free the element itself or manipulate it otherwise.
+ *
+ * Using list_del on a pure list head (like in the example at the top of
+ * this file) will NOT remove the first element from
+ * the list but rather reset the list as empty list.
+ *
+ * Example:
+ * list_del(&foo->entry);
+ *
+ * @param entry The element to remove.
+ */
+static inline void
+list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+static inline void
+list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * Check if the list is empty.
+ *
+ * Example:
+ * list_empty(&bar->list_of_foos);
+ *
+ * @return True if the list contains one or more elements or False otherwise.
+ */
+static inline bool
+list_empty(struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * Returns a pointer to the container of this list element.
+ *
+ * Example:
+ * struct foo* f;
+ * f = container_of(&foo->entry, struct foo, entry);
+ * assert(f == foo);
+ *
+ * @param ptr Pointer to the struct list_head.
+ * @param type Data type of the list element.
+ * @param member Member name of the struct list_head field in the list element.
+ * @return A pointer to the data struct containing the list head.
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) \
+ (type *)((char *)(ptr) - (char *) &((type *)0)->member)
+#endif
+
+/**
+ * Alias of container_of
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * Retrieve the first list entry for the given list pointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct list_head field in the list element.
+ * @return A pointer to the first list element.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * Retrieve the last list entry for the given listpointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct list_head field in the list element.
+ * @return A pointer to the last list element.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+#define __container_of(ptr, sample, member) \
+ (void *)container_of((ptr), typeof(*(sample)), member)
+
+/**
+ * Loop through the list given by head and set pos to struct in the list.
+ *
+ * Example:
+ * struct foo *iterator;
+ * list_for_each_entry(iterator, &bar->list_of_foos, entry) {
+ * [modify iterator]
+ * }
+ *
+ * This macro is not safe for node deletion. Use list_for_each_entry_safe
+ * instead.
+ *
+ * @param pos Iterator variable of the type of the list elements.
+ * @param head List head
+ * @param member Member name of the struct list_head in the list elements.
+ *
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = __container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.next, pos, member))
+
+/**
+ * Loop through the list, keeping a backup pointer to the element. This
+ * macro allows for the deletion of a list element while looping through the
+ * list.
+ *
+ * See list_for_each_entry for more details.
+ */
+#define list_for_each_entry_safe(pos, tmp, head, member) \
+ for (pos = __container_of((head)->next, pos, member), \
+ tmp = __container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
+
+
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = __container_of((head)->prev, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.prev, pos, member))
+
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = __container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.next, pos, member))
+
+#define list_for_each_entry_continue_reverse(pos, head, member) \
+ for (pos = __container_of(pos->member.prev, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.prev, pos, member))
+
+#define list_for_each_entry_from(pos, head, member) \
+ for (; \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.next, pos, member))
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/notify.h b/drivers/gpu/drm/nouveau/include/nvif/notify.h
new file mode 100644
index 000000000..9ebfa3b45
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/notify.h
@@ -0,0 +1,39 @@
+#ifndef __NVIF_NOTIFY_H__
+#define __NVIF_NOTIFY_H__
+
+struct nvif_notify {
+ struct nvif_object *object;
+ int index;
+
+#define NVIF_NOTIFY_USER 0
+#define NVIF_NOTIFY_WORK 1
+ unsigned long flags;
+ atomic_t putcnt;
+ void (*dtor)(struct nvif_notify *);
+#define NVIF_NOTIFY_DROP 0
+#define NVIF_NOTIFY_KEEP 1
+ int (*func)(struct nvif_notify *);
+
+ /* this is const for a *very* good reason - the data might be on the
+ * stack from an irq handler. if you're not nvif/notify.c then you
+ * should probably think twice before casting it away...
+ */
+ const void *data;
+ u32 size;
+ struct work_struct work;
+};
+
+int nvif_notify_init(struct nvif_object *, void (*dtor)(struct nvif_notify *),
+ int (*func)(struct nvif_notify *), bool work, u8 type,
+ void *data, u32 size, u32 reply, struct nvif_notify *);
+int nvif_notify_fini(struct nvif_notify *);
+int nvif_notify_get(struct nvif_notify *);
+int nvif_notify_put(struct nvif_notify *);
+int nvif_notify(const void *, u32, const void *, u32);
+
+int nvif_notify_new(struct nvif_object *, int (*func)(struct nvif_notify *),
+ bool work, u8 type, void *data, u32 size, u32 reply,
+ struct nvif_notify **);
+void nvif_notify_ref(struct nvif_notify *, struct nvif_notify **);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h
new file mode 100644
index 000000000..04c874707
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/object.h
@@ -0,0 +1,75 @@
+#ifndef __NVIF_OBJECT_H__
+#define __NVIF_OBJECT_H__
+
+#include <nvif/os.h>
+
+struct nvif_object {
+ struct nvif_object *parent;
+ struct nvif_object *object; /*XXX: hack for nvif_object() */
+ struct kref refcount;
+ u32 handle;
+ u32 oclass;
+ void *data;
+ u32 size;
+ void *priv; /*XXX: hack */
+ void (*dtor)(struct nvif_object *);
+ struct {
+ void __iomem *ptr;
+ u32 size;
+ } map;
+};
+
+int nvif_object_init(struct nvif_object *, void (*dtor)(struct nvif_object *),
+ u32 handle, u32 oclass, void *, u32,
+ struct nvif_object *);
+void nvif_object_fini(struct nvif_object *);
+int nvif_object_new(struct nvif_object *, u32 handle, u32 oclass,
+ void *, u32, struct nvif_object **);
+void nvif_object_ref(struct nvif_object *, struct nvif_object **);
+int nvif_object_ioctl(struct nvif_object *, void *, u32, void **);
+int nvif_object_sclass(struct nvif_object *, u32 *, int);
+u32 nvif_object_rd(struct nvif_object *, int, u64);
+void nvif_object_wr(struct nvif_object *, int, u64, u32);
+int nvif_object_mthd(struct nvif_object *, u32, void *, u32);
+int nvif_object_map(struct nvif_object *);
+void nvif_object_unmap(struct nvif_object *);
+
+#define nvif_object(a) (a)->object
+
+#define ioread8_native ioread8
+#define iowrite8_native iowrite8
+#define nvif_rd(a,b,c) ({ \
+ struct nvif_object *_object = nvif_object(a); \
+ u32 _data; \
+ if (likely(_object->map.ptr)) \
+ _data = ioread##b##_native((u8 __iomem *)_object->map.ptr + (c)); \
+ else \
+ _data = nvif_object_rd(_object, (b) / 8, (c)); \
+ _data; \
+})
+#define nvif_wr(a,b,c,d) ({ \
+ struct nvif_object *_object = nvif_object(a); \
+ if (likely(_object->map.ptr)) \
+ iowrite##b##_native((d), (u8 __iomem *)_object->map.ptr + (c)); \
+ else \
+ nvif_object_wr(_object, (b) / 8, (c), (d)); \
+})
+#define nvif_rd08(a,b) ({ u8 _v = nvif_rd((a), 8, (b)); _v; })
+#define nvif_rd16(a,b) ({ u16 _v = nvif_rd((a), 16, (b)); _v; })
+#define nvif_rd32(a,b) ({ u32 _v = nvif_rd((a), 32, (b)); _v; })
+#define nvif_wr08(a,b,c) nvif_wr((a), 8, (b), (u8)(c))
+#define nvif_wr16(a,b,c) nvif_wr((a), 16, (b), (u16)(c))
+#define nvif_wr32(a,b,c) nvif_wr((a), 32, (b), (u32)(c))
+#define nvif_mask(a,b,c,d) ({ \
+ u32 _v = nvif_rd32(nvif_object(a), (b)); \
+ nvif_wr32(nvif_object(a), (b), (_v & ~(c)) | (d)); \
+ _v; \
+})
+
+#define nvif_mthd(a,b,c,d) nvif_object_mthd(nvif_object(a), (b), (c), (d))
+
+/*XXX*/
+#include <core/object.h>
+#define nvxx_object(a) ((struct nvkm_object *)nvif_object(a)->priv)
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h
new file mode 100644
index 000000000..bdd05ee7e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/os.h
@@ -0,0 +1,44 @@
+#ifndef __NOUVEAU_OS_H__
+#define __NOUVEAU_OS_H__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/bitops.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/delay.h>
+#include <linux/io-mapping.h>
+#include <linux/acpi.h>
+#include <linux/vmalloc.h>
+#include <linux/dmi.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+#include <linux/log2.h>
+#include <linux/pm_runtime.h>
+#include <linux/power_supply.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/unaligned.h>
+
+#ifndef ioread32_native
+#ifdef __BIG_ENDIAN
+#define ioread16_native ioread16be
+#define iowrite16_native iowrite16be
+#define ioread32_native ioread32be
+#define iowrite32_native iowrite32be
+#else /* def __BIG_ENDIAN */
+#define ioread16_native ioread16
+#define iowrite16_native iowrite16
+#define ioread32_native ioread32
+#define iowrite32_native iowrite32
+#endif /* def __BIG_ENDIAN else */
+#endif /* !ioread32_native */
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/unpack.h b/drivers/gpu/drm/nouveau/include/nvif/unpack.h
new file mode 100644
index 000000000..5933188b4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/unpack.h
@@ -0,0 +1,24 @@
+#ifndef __NVIF_UNPACK_H__
+#define __NVIF_UNPACK_H__
+
+#define nvif_unvers(d) ({ \
+ ret = (size == sizeof(d)) ? 0 : -ENOSYS; \
+ (ret == 0); \
+})
+
+#define nvif_unpack(d,vl,vh,m) ({ \
+ if ((vl) == 0 || ret == -ENOSYS) { \
+ int _size = sizeof(d); \
+ if (_size <= size && (d).version >= (vl) && \
+ (d).version <= (vh)) { \
+ data = (u8 *)data + _size; \
+ size = size - _size; \
+ ret = ((m) || !size) ? 0 : -E2BIG; \
+ } else { \
+ ret = -ENOSYS; \
+ } \
+ } \
+ (ret == 0); \
+})
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
new file mode 100644
index 000000000..a35b38244
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
@@ -0,0 +1,55 @@
+#ifndef __NVKM_CLIENT_H__
+#define __NVKM_CLIENT_H__
+#include <core/namedb.h>
+
+struct nvkm_client {
+ struct nvkm_namedb namedb;
+ struct nvkm_handle *root;
+ struct nvkm_object *device;
+ char name[32];
+ u32 debug;
+ struct nvkm_vm *vm;
+ bool super;
+ void *data;
+
+ int (*ntfy)(const void *, u32, const void *, u32);
+ struct nvkm_client_notify *notify[16];
+};
+
+static inline struct nvkm_client *
+nv_client(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_CLIENT_CLASS)))
+ nv_assert("BAD CAST -> NvClient, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline struct nvkm_client *
+nvkm_client(void *obj)
+{
+ struct nvkm_object *client = nv_object(obj);
+ while (client && !(nv_iclass(client, NV_CLIENT_CLASS)))
+ client = client->parent;
+ return (void *)client;
+}
+
+#define nvkm_client_create(n,c,oc,od,d) \
+ nvkm_client_create_((n), (c), (oc), (od), sizeof(**d), (void **)d)
+
+int nvkm_client_create_(const char *name, u64 device, const char *cfg,
+ const char *dbg, int, void **);
+#define nvkm_client_destroy(p) \
+ nvkm_namedb_destroy(&(p)->base)
+
+int nvkm_client_init(struct nvkm_client *);
+int nvkm_client_fini(struct nvkm_client *, bool suspend);
+const char *nvkm_client_name(void *obj);
+
+int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *,
+ void *data, u32 size);
+int nvkm_client_notify_del(struct nvkm_client *, int index);
+int nvkm_client_notify_get(struct nvkm_client *, int index);
+int nvkm_client_notify_put(struct nvkm_client *, int index);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
new file mode 100644
index 000000000..d07cb860b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
@@ -0,0 +1,18 @@
+#ifndef __NVKM_DEBUG_H__
+#define __NVKM_DEBUG_H__
+extern int nv_info_debug_level;
+
+#define NV_DBG_FATAL 0
+#define NV_DBG_ERROR 1
+#define NV_DBG_WARN 2
+#define NV_DBG_INFO nv_info_debug_level
+#define NV_DBG_DEBUG 4
+#define NV_DBG_TRACE 5
+#define NV_DBG_PARANOIA 6
+#define NV_DBG_SPAM 7
+
+#define NV_DBG_INFO_NORMAL 3
+#define NV_DBG_INFO_SILENT NV_DBG_DEBUG
+
+#define nv_debug_level(a) nv_info_debug_level = NV_DBG_INFO_##a
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
new file mode 100644
index 000000000..333db33a1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -0,0 +1,101 @@
+#ifndef __NVKM_DEVICE_H__
+#define __NVKM_DEVICE_H__
+#include <core/engine.h>
+#include <core/event.h>
+
+struct nvkm_device {
+ struct nvkm_engine engine;
+ struct list_head head;
+
+ struct pci_dev *pdev;
+ struct platform_device *platformdev;
+ u64 handle;
+
+ struct nvkm_event event;
+
+ const char *cfgopt;
+ const char *dbgopt;
+ const char *name;
+ const char *cname;
+ u64 disable_mask;
+
+ 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_E0 = 0xe0,
+ GM100 = 0x110,
+ } card_type;
+ u32 chipset;
+ u8 chiprev;
+ u32 crystal;
+
+ struct nvkm_oclass *oclass[NVDEV_SUBDEV_NR];
+ struct nvkm_object *subdev[NVDEV_SUBDEV_NR];
+
+ struct {
+ struct notifier_block nb;
+ } acpi;
+};
+
+struct nvkm_device *nvkm_device_find(u64 name);
+int nvkm_device_list(u64 *name, int size);
+
+struct nvkm_device *nv_device(void *obj);
+
+static inline bool
+nv_device_match(struct nvkm_object *object, u16 dev, u16 ven, u16 sub)
+{
+ struct nvkm_device *device = nv_device(object);
+ return device->pdev->device == dev &&
+ device->pdev->subsystem_vendor == ven &&
+ device->pdev->subsystem_device == sub;
+}
+
+static inline bool
+nv_device_is_pci(struct nvkm_device *device)
+{
+ return device->pdev != NULL;
+}
+
+static inline bool
+nv_device_is_cpu_coherent(struct nvkm_device *device)
+{
+ return (!IS_ENABLED(CONFIG_ARM) && nv_device_is_pci(device));
+}
+
+static inline struct device *
+nv_device_base(struct nvkm_device *device)
+{
+ return nv_device_is_pci(device) ? &device->pdev->dev :
+ &device->platformdev->dev;
+}
+
+resource_size_t
+nv_device_resource_start(struct nvkm_device *device, unsigned int bar);
+
+resource_size_t
+nv_device_resource_len(struct nvkm_device *device, unsigned int bar);
+
+int
+nv_device_get_irq(struct nvkm_device *device, bool stall);
+
+struct platform_device;
+
+enum nv_bus_type {
+ NVKM_BUS_PCI,
+ NVKM_BUS_PLATFORM,
+};
+
+#define nvkm_device_create(p,t,n,s,c,d,u) \
+ nvkm_device_create_((void *)(p), (t), (n), (s), (c), (d), \
+ sizeof(**u), (void **)u)
+int nvkm_device_create_(void *, enum nv_bus_type type, u64 name,
+ const char *sname, const char *cfg, const char *dbg,
+ int, void **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h b/drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h
new file mode 100644
index 000000000..60c5888b5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h
@@ -0,0 +1,62 @@
+#ifndef __NVKM_DEVIDX_H__
+#define __NVKM_DEVIDX_H__
+enum nvkm_devidx {
+ 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_IBUS,
+ 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_FUSE,
+ NVDEV_SUBDEV_MXM,
+ NVDEV_SUBDEV_MC,
+ NVDEV_SUBDEV_BUS,
+ NVDEV_SUBDEV_TIMER,
+ NVDEV_SUBDEV_FB,
+ NVDEV_SUBDEV_LTC,
+ NVDEV_SUBDEV_INSTMEM,
+ NVDEV_SUBDEV_MMU,
+ NVDEV_SUBDEV_BAR,
+ NVDEV_SUBDEV_PMU,
+ NVDEV_SUBDEV_VOLT,
+ NVDEV_SUBDEV_THERM,
+ NVDEV_SUBDEV_CLK,
+
+ NVDEV_ENGINE_FIRST,
+ NVDEV_ENGINE_DMAOBJ = NVDEV_ENGINE_FIRST,
+ NVDEV_ENGINE_IFB,
+ NVDEV_ENGINE_FIFO,
+ NVDEV_ENGINE_SW,
+ NVDEV_ENGINE_GR,
+ NVDEV_ENGINE_MPEG,
+ NVDEV_ENGINE_ME,
+ NVDEV_ENGINE_VP,
+ NVDEV_ENGINE_CIPHER,
+ NVDEV_ENGINE_BSP,
+ NVDEV_ENGINE_MSPPP,
+ NVDEV_ENGINE_CE0,
+ NVDEV_ENGINE_CE1,
+ NVDEV_ENGINE_CE2,
+ NVDEV_ENGINE_VIC,
+ NVDEV_ENGINE_MSENC,
+ NVDEV_ENGINE_DISP,
+ NVDEV_ENGINE_PM,
+ NVDEV_ENGINE_MSVLD,
+ NVDEV_ENGINE_SEC,
+ NVDEV_ENGINE_MSPDEC,
+
+ NVDEV_SUBDEV_NR,
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
new file mode 100644
index 000000000..1bf2e8eb4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
@@ -0,0 +1,51 @@
+#ifndef __NVKM_ENGCTX_H__
+#define __NVKM_ENGCTX_H__
+#include <core/gpuobj.h>
+
+#include <subdev/mmu.h>
+
+#define NV_ENGCTX_(eng,var) (NV_ENGCTX_CLASS | ((var) << 8) | (eng))
+#define NV_ENGCTX(name,var) NV_ENGCTX_(NVDEV_ENGINE_##name, (var))
+
+struct nvkm_engctx {
+ struct nvkm_gpuobj gpuobj;
+ struct nvkm_vma vma;
+ struct list_head head;
+ unsigned long save;
+ u64 addr;
+};
+
+static inline struct nvkm_engctx *
+nv_engctx(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_ENGCTX_CLASS)))
+ nv_assert("BAD CAST -> NvEngCtx, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_engctx_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create_((p), (e), (c), (g), (s), (a), (f), \
+ sizeof(**d), (void **)d)
+
+int nvkm_engctx_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, struct nvkm_object *,
+ u32 size, u32 align, u32 flags,
+ int length, void **data);
+void nvkm_engctx_destroy(struct nvkm_engctx *);
+int nvkm_engctx_init(struct nvkm_engctx *);
+int nvkm_engctx_fini(struct nvkm_engctx *, bool suspend);
+
+int _nvkm_engctx_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_engctx_dtor(struct nvkm_object *);
+int _nvkm_engctx_init(struct nvkm_object *);
+int _nvkm_engctx_fini(struct nvkm_object *, bool suspend);
+#define _nvkm_engctx_rd32 _nvkm_gpuobj_rd32
+#define _nvkm_engctx_wr32 _nvkm_gpuobj_wr32
+
+struct nvkm_object *nvkm_engctx_get(struct nvkm_engine *, u64 addr);
+void nvkm_engctx_put(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
new file mode 100644
index 000000000..faf0fd2f0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
@@ -0,0 +1,56 @@
+#ifndef __NVKM_ENGINE_H__
+#define __NVKM_ENGINE_H__
+#include <core/subdev.h>
+
+#define NV_ENGINE_(eng,var) (NV_ENGINE_CLASS | ((var) << 8) | (eng))
+#define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var))
+
+struct nvkm_engine {
+ struct nvkm_subdev subdev;
+ struct nvkm_oclass *cclass;
+ struct nvkm_oclass *sclass;
+
+ struct list_head contexts;
+ spinlock_t lock;
+
+ void (*tile_prog)(struct nvkm_engine *, int region);
+ int (*tlb_flush)(struct nvkm_engine *);
+};
+
+static inline struct nvkm_engine *
+nv_engine(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_ENGINE_CLASS)))
+ nv_assert("BAD CAST -> NvEngine, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline int
+nv_engidx(struct nvkm_engine *engine)
+{
+ return nv_subidx(&engine->subdev);
+}
+
+struct nvkm_engine *nvkm_engine(void *obj, int idx);
+
+#define nvkm_engine_create(p,e,c,d,i,f,r) \
+ nvkm_engine_create_((p), (e), (c), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+
+#define nvkm_engine_destroy(p) \
+ nvkm_subdev_destroy(&(p)->subdev)
+#define nvkm_engine_init(p) \
+ nvkm_subdev_init(&(p)->subdev)
+#define nvkm_engine_fini(p,s) \
+ nvkm_subdev_fini(&(p)->subdev, (s))
+
+int nvkm_engine_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, bool, const char *,
+ const char *, int, void **);
+
+#define _nvkm_engine_dtor _nvkm_subdev_dtor
+#define _nvkm_engine_init _nvkm_subdev_init
+#define _nvkm_engine_fini _nvkm_subdev_fini
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h b/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h
new file mode 100644
index 000000000..e76f76f11
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h
@@ -0,0 +1,21 @@
+#ifndef __NVKM_ENUM_H__
+#define __NVKM_ENUM_H__
+#include <core/os.h>
+
+struct nvkm_enum {
+ u32 value;
+ const char *name;
+ const void *data;
+ u32 data2;
+};
+
+const struct nvkm_enum *nvkm_enum_find(const struct nvkm_enum *, u32 value);
+const struct nvkm_enum *nvkm_enum_print(const struct nvkm_enum *, u32 value);
+
+struct nvkm_bitfield {
+ u32 mask;
+ const char *name;
+};
+
+void nvkm_bitfield_print(const struct nvkm_bitfield *, u32 value);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
new file mode 100644
index 000000000..b98fe2de5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_EVENT_H__
+#define __NVKM_EVENT_H__
+#include <core/os.h>
+struct nvkm_notify;
+struct nvkm_object;
+
+struct nvkm_event {
+ const struct nvkm_event_func *func;
+
+ int types_nr;
+ int index_nr;
+
+ spinlock_t refs_lock;
+ spinlock_t list_lock;
+ struct list_head list;
+ int *refs;
+};
+
+struct nvkm_event_func {
+ int (*ctor)(struct nvkm_object *, void *data, u32 size,
+ struct nvkm_notify *);
+ void (*send)(void *data, u32 size, struct nvkm_notify *);
+ void (*init)(struct nvkm_event *, int type, int index);
+ void (*fini)(struct nvkm_event *, int type, int index);
+};
+
+int nvkm_event_init(const struct nvkm_event_func *func, int types_nr,
+ int index_nr, struct nvkm_event *);
+void nvkm_event_fini(struct nvkm_event *);
+void nvkm_event_get(struct nvkm_event *, u32 types, int index);
+void nvkm_event_put(struct nvkm_event *, u32 types, int index);
+void nvkm_event_send(struct nvkm_event *, u32 types, int index,
+ void *data, u32 size);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
new file mode 100644
index 000000000..e0187e7ab
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
@@ -0,0 +1,64 @@
+#ifndef __NVKM_GPUOBJ_H__
+#define __NVKM_GPUOBJ_H__
+#include <core/object.h>
+#include <core/mm.h>
+struct nvkm_vma;
+struct nvkm_vm;
+
+#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001
+#define NVOBJ_FLAG_ZERO_FREE 0x00000002
+#define NVOBJ_FLAG_HEAP 0x00000004
+
+struct nvkm_gpuobj {
+ struct nvkm_object object;
+ struct nvkm_object *parent;
+ struct nvkm_mm_node *node;
+ struct nvkm_mm heap;
+
+ u32 flags;
+ u64 addr;
+ u32 size;
+};
+
+static inline struct nvkm_gpuobj *
+nv_gpuobj(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_GPUOBJ_CLASS)))
+ nv_assert("BAD CAST -> NvGpuObj, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_gpuobj_create(p,e,c,v,g,s,a,f,d) \
+ nvkm_gpuobj_create_((p), (e), (c), (v), (g), (s), (a), (f), \
+ sizeof(**d), (void **)d)
+#define nvkm_gpuobj_init(p) nvkm_object_init(&(p)->object)
+#define nvkm_gpuobj_fini(p,s) nvkm_object_fini(&(p)->object, (s))
+int nvkm_gpuobj_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ struct nvkm_object *, u32 size, u32 align,
+ u32 flags, int length, void **);
+void nvkm_gpuobj_destroy(struct nvkm_gpuobj *);
+
+int nvkm_gpuobj_new(struct nvkm_object *, struct nvkm_object *, u32 size,
+ u32 align, u32 flags, struct nvkm_gpuobj **);
+int nvkm_gpuobj_dup(struct nvkm_object *, struct nvkm_gpuobj *,
+ struct nvkm_gpuobj **);
+int nvkm_gpuobj_map(struct nvkm_gpuobj *, u32 acc, struct nvkm_vma *);
+int nvkm_gpuobj_map_vm(struct nvkm_gpuobj *, struct nvkm_vm *, u32 access,
+ struct nvkm_vma *);
+void nvkm_gpuobj_unmap(struct nvkm_vma *);
+
+static inline void
+nvkm_gpuobj_ref(struct nvkm_gpuobj *obj, struct nvkm_gpuobj **ref)
+{
+ nvkm_object_ref(&obj->object, (struct nvkm_object **)ref);
+}
+
+void _nvkm_gpuobj_dtor(struct nvkm_object *);
+int _nvkm_gpuobj_init(struct nvkm_object *);
+int _nvkm_gpuobj_fini(struct nvkm_object *, bool);
+u32 _nvkm_gpuobj_rd32(struct nvkm_object *, u64);
+void _nvkm_gpuobj_wr32(struct nvkm_object *, u64, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h b/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
new file mode 100644
index 000000000..67f384d09
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_HANDLE_H__
+#define __NVKM_HANDLE_H__
+#include <core/os.h>
+struct nvkm_object;
+
+struct nvkm_handle {
+ struct nvkm_namedb *namedb;
+ struct list_head node;
+
+ struct list_head head;
+ struct list_head tree;
+ u32 name;
+ u32 priv;
+
+ u8 route;
+ u64 token;
+
+ struct nvkm_handle *parent;
+ struct nvkm_object *object;
+};
+
+int nvkm_handle_create(struct nvkm_object *, u32 parent, u32 handle,
+ struct nvkm_object *, struct nvkm_handle **);
+void nvkm_handle_destroy(struct nvkm_handle *);
+int nvkm_handle_init(struct nvkm_handle *);
+int nvkm_handle_fini(struct nvkm_handle *, bool suspend);
+
+struct nvkm_object *nvkm_handle_ref(struct nvkm_object *, u32 name);
+
+struct nvkm_handle *nvkm_handle_get_class(struct nvkm_object *, u16);
+struct nvkm_handle *nvkm_handle_get_vinst(struct nvkm_object *, u64);
+struct nvkm_handle *nvkm_handle_get_cinst(struct nvkm_object *, u32);
+void nvkm_handle_put(struct nvkm_handle *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h
new file mode 100644
index 000000000..88971eb37
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_IOCTL_H__
+#define __NVKM_IOCTL_H__
+#include <core/os.h>
+struct nvkm_client;
+
+int nvkm_ioctl(struct nvkm_client *, bool, void *, u32, void **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h
new file mode 100644
index 000000000..096eb1a62
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h
@@ -0,0 +1,40 @@
+#ifndef __NVKM_MM_H__
+#define __NVKM_MM_H__
+#include <core/os.h>
+
+struct nvkm_mm_node {
+ struct list_head nl_entry;
+ struct list_head fl_entry;
+ struct list_head rl_entry;
+
+#define NVKM_MM_HEAP_ANY 0x00
+ u8 heap;
+#define NVKM_MM_TYPE_NONE 0x00
+#define NVKM_MM_TYPE_HOLE 0xff
+ u8 type;
+ u32 offset;
+ u32 length;
+};
+
+struct nvkm_mm {
+ struct list_head nodes;
+ struct list_head free;
+
+ u32 block_size;
+ int heap_nodes;
+};
+
+static inline bool
+nvkm_mm_initialised(struct nvkm_mm *mm)
+{
+ return mm->block_size != 0;
+}
+
+int nvkm_mm_init(struct nvkm_mm *, u32 offset, u32 length, u32 block);
+int nvkm_mm_fini(struct nvkm_mm *);
+int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
+ u32 size_min, u32 align, struct nvkm_mm_node **);
+int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
+ u32 size_min, u32 align, struct nvkm_mm_node **);
+void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h b/drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
new file mode 100644
index 000000000..4cfe16fcd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
@@ -0,0 +1,53 @@
+#ifndef __NVKM_NAMEDB_H__
+#define __NVKM_NAMEDB_H__
+#include <core/parent.h>
+struct nvkm_handle;
+
+struct nvkm_namedb {
+ struct nvkm_parent parent;
+ rwlock_t lock;
+ struct list_head list;
+};
+
+static inline struct nvkm_namedb *
+nv_namedb(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_NAMEDB_CLASS)))
+ nv_assert("BAD CAST -> NvNameDB, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_namedb_create(p,e,c,v,s,m,d) \
+ nvkm_namedb_create_((p), (e), (c), (v), (s), (m), \
+ sizeof(**d), (void **)d)
+#define nvkm_namedb_init(p) \
+ nvkm_parent_init(&(p)->parent)
+#define nvkm_namedb_fini(p,s) \
+ nvkm_parent_fini(&(p)->parent, (s))
+#define nvkm_namedb_destroy(p) \
+ nvkm_parent_destroy(&(p)->parent)
+
+int nvkm_namedb_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ struct nvkm_oclass *, u64 engcls,
+ int size, void **);
+
+int _nvkm_namedb_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+#define _nvkm_namedb_dtor _nvkm_parent_dtor
+#define _nvkm_namedb_init _nvkm_parent_init
+#define _nvkm_namedb_fini _nvkm_parent_fini
+
+int nvkm_namedb_insert(struct nvkm_namedb *, u32 name, struct nvkm_object *,
+ struct nvkm_handle *);
+void nvkm_namedb_remove(struct nvkm_handle *);
+
+struct nvkm_handle *nvkm_namedb_get(struct nvkm_namedb *, u32);
+struct nvkm_handle *nvkm_namedb_get_class(struct nvkm_namedb *, u16);
+struct nvkm_handle *nvkm_namedb_get_vinst(struct nvkm_namedb *, u64);
+struct nvkm_handle *nvkm_namedb_get_cinst(struct nvkm_namedb *, u32);
+void nvkm_namedb_put(struct nvkm_handle *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/notify.h b/drivers/gpu/drm/nouveau/include/nvkm/core/notify.h
new file mode 100644
index 000000000..753d08c17
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/notify.h
@@ -0,0 +1,38 @@
+#ifndef __NVKM_NOTIFY_H__
+#define __NVKM_NOTIFY_H__
+#include <core/os.h>
+struct nvkm_object;
+
+struct nvkm_notify {
+ struct nvkm_event *event;
+ struct list_head head;
+#define NVKM_NOTIFY_USER 0
+#define NVKM_NOTIFY_WORK 1
+ unsigned long flags;
+ int block;
+#define NVKM_NOTIFY_DROP 0
+#define NVKM_NOTIFY_KEEP 1
+ int (*func)(struct nvkm_notify *);
+
+ /* set by nvkm_event ctor */
+ u32 types;
+ int index;
+ u32 size;
+
+ struct work_struct work;
+ /* this is const for a *very* good reason - the data might be on the
+ * stack from an irq handler. if you're not core/notify.c then you
+ * should probably think twice before casting it away...
+ */
+ const void *data;
+};
+
+int nvkm_notify_init(struct nvkm_object *, struct nvkm_event *,
+ int (*func)(struct nvkm_notify *), bool work,
+ void *data, u32 size, u32 reply,
+ struct nvkm_notify *);
+void nvkm_notify_fini(struct nvkm_notify *);
+void nvkm_notify_get(struct nvkm_notify *);
+void nvkm_notify_put(struct nvkm_notify *);
+void nvkm_notify_send(struct nvkm_notify *, void *data, u32 size);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
new file mode 100644
index 000000000..6e3cd3908
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
@@ -0,0 +1,203 @@
+#ifndef __NVKM_OBJECT_H__
+#define __NVKM_OBJECT_H__
+#include <core/os.h>
+#include <core/printk.h>
+
+#define NV_PARENT_CLASS 0x80000000
+#define NV_NAMEDB_CLASS 0x40000000
+#define NV_CLIENT_CLASS 0x20000000
+#define NV_SUBDEV_CLASS 0x10000000
+#define NV_ENGINE_CLASS 0x08000000
+#define NV_MEMOBJ_CLASS 0x04000000
+#define NV_GPUOBJ_CLASS 0x02000000
+#define NV_ENGCTX_CLASS 0x01000000
+#define NV_OBJECT_CLASS 0x0000ffff
+
+struct nvkm_object {
+ struct nvkm_oclass *oclass;
+ struct nvkm_object *parent;
+ struct nvkm_engine *engine;
+ atomic_t refcount;
+ atomic_t usecount;
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+#define NVKM_OBJECT_MAGIC 0x75ef0bad
+ struct list_head list;
+ u32 _magic;
+#endif
+};
+
+static inline struct nvkm_object *
+nv_object(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (likely(obj)) {
+ struct nvkm_object *object = obj;
+ if (unlikely(object->_magic != NVKM_OBJECT_MAGIC))
+ nv_assert("BAD CAST -> NvObject, invalid magic");
+ }
+#endif
+ return obj;
+}
+
+#define nvkm_object_create(p,e,c,s,d) \
+ nvkm_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d)
+int nvkm_object_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32, int size, void **);
+void nvkm_object_destroy(struct nvkm_object *);
+int nvkm_object_init(struct nvkm_object *);
+int nvkm_object_fini(struct nvkm_object *, bool suspend);
+
+int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+extern struct nvkm_ofuncs nvkm_object_ofuncs;
+
+/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
+ * ".data". */
+struct nvkm_oclass {
+ u32 handle;
+ struct nvkm_ofuncs * const ofuncs;
+ struct nvkm_omthds * const omthds;
+ struct lock_class_key lock_class_key;
+};
+
+#define nv_oclass(o) nv_object(o)->oclass
+#define nv_hclass(o) nv_oclass(o)->handle
+#define nv_iclass(o,i) (nv_hclass(o) & (i))
+#define nv_mclass(o) nv_iclass(o, NV_OBJECT_CLASS)
+
+static inline struct nvkm_object *
+nv_pclass(struct nvkm_object *parent, u32 oclass)
+{
+ while (parent && !nv_iclass(parent, oclass))
+ parent = parent->parent;
+ return parent;
+}
+
+struct nvkm_omthds {
+ u32 start;
+ u32 limit;
+ int (*call)(struct nvkm_object *, u32, void *, u32);
+};
+
+struct nvkm_event;
+struct nvkm_ofuncs {
+ int (*ctor)(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *data, u32 size,
+ struct nvkm_object **);
+ void (*dtor)(struct nvkm_object *);
+ int (*init)(struct nvkm_object *);
+ int (*fini)(struct nvkm_object *, bool suspend);
+ int (*mthd)(struct nvkm_object *, u32, void *, u32);
+ int (*ntfy)(struct nvkm_object *, u32, struct nvkm_event **);
+ int (* map)(struct nvkm_object *, u64 *, u32 *);
+ u8 (*rd08)(struct nvkm_object *, u64 offset);
+ u16 (*rd16)(struct nvkm_object *, u64 offset);
+ u32 (*rd32)(struct nvkm_object *, u64 offset);
+ void (*wr08)(struct nvkm_object *, u64 offset, u8 data);
+ void (*wr16)(struct nvkm_object *, u64 offset, u16 data);
+ void (*wr32)(struct nvkm_object *, u64 offset, u32 data);
+};
+
+static inline struct nvkm_ofuncs *
+nv_ofuncs(void *obj)
+{
+ return nv_oclass(obj)->ofuncs;
+}
+
+int nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **);
+int nvkm_object_inc(struct nvkm_object *);
+int nvkm_object_dec(struct nvkm_object *, bool suspend);
+void nvkm_object_debug(void);
+
+static inline int
+nv_exec(void *obj, u32 mthd, void *data, u32 size)
+{
+ struct nvkm_omthds *method = nv_oclass(obj)->omthds;
+
+ while (method && method->call) {
+ if (mthd >= method->start && mthd <= method->limit)
+ return method->call(obj, mthd, data, size);
+ method++;
+ }
+
+ return -EINVAL;
+}
+
+static inline int
+nv_call(void *obj, u32 mthd, u32 data)
+{
+ return nv_exec(obj, mthd, &data, sizeof(data));
+}
+
+static inline u8
+nv_ro08(void *obj, u64 addr)
+{
+ u8 data = nv_ofuncs(obj)->rd08(obj, addr);
+ nv_spam(obj, "nv_ro08 0x%08llx 0x%02x\n", addr, data);
+ return data;
+}
+
+static inline u16
+nv_ro16(void *obj, u64 addr)
+{
+ u16 data = nv_ofuncs(obj)->rd16(obj, addr);
+ nv_spam(obj, "nv_ro16 0x%08llx 0x%04x\n", addr, data);
+ return data;
+}
+
+static inline u32
+nv_ro32(void *obj, u64 addr)
+{
+ u32 data = nv_ofuncs(obj)->rd32(obj, addr);
+ nv_spam(obj, "nv_ro32 0x%08llx 0x%08x\n", addr, data);
+ return data;
+}
+
+static inline void
+nv_wo08(void *obj, u64 addr, u8 data)
+{
+ nv_spam(obj, "nv_wo08 0x%08llx 0x%02x\n", addr, data);
+ nv_ofuncs(obj)->wr08(obj, addr, data);
+}
+
+static inline void
+nv_wo16(void *obj, u64 addr, u16 data)
+{
+ nv_spam(obj, "nv_wo16 0x%08llx 0x%04x\n", addr, data);
+ nv_ofuncs(obj)->wr16(obj, addr, data);
+}
+
+static inline void
+nv_wo32(void *obj, u64 addr, u32 data)
+{
+ nv_spam(obj, "nv_wo32 0x%08llx 0x%08x\n", addr, data);
+ nv_ofuncs(obj)->wr32(obj, addr, data);
+}
+
+static inline u32
+nv_mo32(void *obj, u64 addr, u32 mask, u32 data)
+{
+ u32 temp = nv_ro32(obj, addr);
+ nv_wo32(obj, addr, (temp & ~mask) | data);
+ return temp;
+}
+
+static inline int
+nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
+{
+ unsigned char c1, c2;
+
+ while (len--) {
+ c1 = nv_ro08(obj, addr++);
+ c2 = *(str++);
+ if (c1 != c2)
+ return c1 - c2;
+ }
+ return 0;
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/option.h b/drivers/gpu/drm/nouveau/include/nvkm/core/option.h
new file mode 100644
index 000000000..532bfa8e3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/option.h
@@ -0,0 +1,17 @@
+#ifndef __NVKM_OPTION_H__
+#define __NVKM_OPTION_H__
+#include <core/os.h>
+
+const char *nvkm_stropt(const char *optstr, const char *opt, int *len);
+bool nvkm_boolopt(const char *optstr, const char *opt, bool value);
+int nvkm_dbgopt(const char *optstr, const char *sub);
+
+/* compares unterminated string 'str' with zero-terminated string 'cmp' */
+static inline int
+strncasecmpz(const char *str, const char *cmp, size_t len)
+{
+ if (strlen(cmp) != len)
+ return len;
+ return strncasecmp(str, cmp, len);
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h
new file mode 100644
index 000000000..cd57e238d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h
@@ -0,0 +1,4 @@
+#ifndef __NVKM_OS_H__
+#define __NVKM_OS_H__
+#include <nvif/os.h>
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/parent.h b/drivers/gpu/drm/nouveau/include/nvkm/core/parent.h
new file mode 100644
index 000000000..837e4fe96
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/parent.h
@@ -0,0 +1,58 @@
+#ifndef __NVKM_PARENT_H__
+#define __NVKM_PARENT_H__
+#include <core/object.h>
+
+struct nvkm_sclass {
+ struct nvkm_sclass *sclass;
+ struct nvkm_engine *engine;
+ struct nvkm_oclass *oclass;
+};
+
+struct nvkm_parent {
+ struct nvkm_object object;
+
+ struct nvkm_sclass *sclass;
+ u64 engine;
+
+ int (*context_attach)(struct nvkm_object *, struct nvkm_object *);
+ int (*context_detach)(struct nvkm_object *, bool suspend,
+ struct nvkm_object *);
+
+ int (*object_attach)(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 name);
+ void (*object_detach)(struct nvkm_object *parent, int cookie);
+};
+
+static inline struct nvkm_parent *
+nv_parent(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!(nv_iclass(obj, NV_PARENT_CLASS))))
+ nv_assert("BAD CAST -> NvParent, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_parent_create(p,e,c,v,s,m,d) \
+ nvkm_parent_create_((p), (e), (c), (v), (s), (m), \
+ sizeof(**d), (void **)d)
+#define nvkm_parent_init(p) \
+ nvkm_object_init(&(p)->object)
+#define nvkm_parent_fini(p,s) \
+ nvkm_object_fini(&(p)->object, (s))
+
+int nvkm_parent_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ struct nvkm_oclass *, u64 engcls,
+ int size, void **);
+void nvkm_parent_destroy(struct nvkm_parent *);
+
+void _nvkm_parent_dtor(struct nvkm_object *);
+#define _nvkm_parent_init nvkm_object_init
+#define _nvkm_parent_fini nvkm_object_fini
+
+int nvkm_parent_sclass(struct nvkm_object *, u16 handle,
+ struct nvkm_object **pengine,
+ struct nvkm_oclass **poclass);
+int nvkm_parent_lclass(struct nvkm_object *, u32 *, int);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/printk.h b/drivers/gpu/drm/nouveau/include/nvkm/core/printk.h
new file mode 100644
index 000000000..836481770
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/printk.h
@@ -0,0 +1,29 @@
+#ifndef __NVKM_PRINTK_H__
+#define __NVKM_PRINTK_H__
+#include <core/os.h>
+#include <core/debug.h>
+struct nvkm_object;
+
+void __printf(3, 4)
+nv_printk_(struct nvkm_object *, int, const char *, ...);
+
+#define nv_printk(o,l,f,a...) do { \
+ if (NV_DBG_##l <= CONFIG_NOUVEAU_DEBUG) \
+ nv_printk_(nv_object(o), NV_DBG_##l, f, ##a); \
+} while(0)
+
+#define nv_fatal(o,f,a...) nv_printk((o), FATAL, f, ##a)
+#define nv_error(o,f,a...) nv_printk((o), ERROR, f, ##a)
+#define nv_warn(o,f,a...) nv_printk((o), WARN, f, ##a)
+#define nv_info(o,f,a...) nv_printk((o), INFO, f, ##a)
+#define nv_debug(o,f,a...) nv_printk((o), DEBUG, f, ##a)
+#define nv_trace(o,f,a...) nv_printk((o), TRACE, f, ##a)
+#define nv_spam(o,f,a...) nv_printk((o), SPAM, f, ##a)
+#define nv_ioctl(o,f,a...) nv_trace(nvkm_client(o), "ioctl: "f, ##a)
+
+#define nv_assert(f,a...) do { \
+ if (NV_DBG_FATAL <= CONFIG_NOUVEAU_DEBUG) \
+ nv_printk_(NULL, NV_DBG_FATAL, f "\n", ##a); \
+ BUG_ON(1); \
+} while(0)
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h
new file mode 100644
index 000000000..cc132eaa1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h
@@ -0,0 +1,20 @@
+#ifndef __NVKM_RAMHT_H__
+#define __NVKM_RAMHT_H__
+#include <core/gpuobj.h>
+
+struct nvkm_ramht {
+ struct nvkm_gpuobj gpuobj;
+ int bits;
+};
+
+int nvkm_ramht_insert(struct nvkm_ramht *, int chid, u32 handle, u32 context);
+void nvkm_ramht_remove(struct nvkm_ramht *, int cookie);
+int nvkm_ramht_new(struct nvkm_object *, struct nvkm_object *, u32 size,
+ u32 align, struct nvkm_ramht **);
+
+static inline void
+nvkm_ramht_ref(struct nvkm_ramht *obj, struct nvkm_ramht **ref)
+{
+ nvkm_gpuobj_ref(&obj->gpuobj, (struct nvkm_gpuobj **)ref);
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
new file mode 100644
index 000000000..6fdc39116
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -0,0 +1,119 @@
+#ifndef __NVKM_SUBDEV_H__
+#define __NVKM_SUBDEV_H__
+#include <core/object.h>
+#include <core/devidx.h>
+
+#define NV_SUBDEV_(sub,var) (NV_SUBDEV_CLASS | ((var) << 8) | (sub))
+#define NV_SUBDEV(name,var) NV_SUBDEV_(NVDEV_SUBDEV_##name, (var))
+
+struct nvkm_subdev {
+ struct nvkm_object object;
+ struct mutex mutex;
+ const char *name;
+ void __iomem *mmio;
+ u32 debug;
+ u32 unit;
+
+ void (*intr)(struct nvkm_subdev *);
+};
+
+static inline struct nvkm_subdev *
+nv_subdev(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_SUBDEV_CLASS)))
+ nv_assert("BAD CAST -> NvSubDev, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline int
+nv_subidx(struct nvkm_subdev *subdev)
+{
+ return nv_hclass(subdev) & 0xff;
+}
+
+struct nvkm_subdev *nvkm_subdev(void *obj, int idx);
+
+#define nvkm_subdev_create(p,e,o,v,s,f,d) \
+ nvkm_subdev_create_((p), (e), (o), (v), (s), (f), \
+ sizeof(**d),(void **)d)
+
+int nvkm_subdev_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ const char *sname, const char *fname,
+ int size, void **);
+void nvkm_subdev_destroy(struct nvkm_subdev *);
+int nvkm_subdev_init(struct nvkm_subdev *);
+int nvkm_subdev_fini(struct nvkm_subdev *, bool suspend);
+void nvkm_subdev_reset(struct nvkm_object *);
+
+void _nvkm_subdev_dtor(struct nvkm_object *);
+int _nvkm_subdev_init(struct nvkm_object *);
+int _nvkm_subdev_fini(struct nvkm_object *, bool suspend);
+
+#define s_printk(s,l,f,a...) do { \
+ if ((s)->debug >= OS_DBG_##l) { \
+ nv_printk((s)->base.parent, (s)->name, l, f, ##a); \
+ } \
+} while(0)
+
+static inline u8
+nv_rd08(void *obj, u32 addr)
+{
+ struct nvkm_subdev *subdev = nv_subdev(obj);
+ u8 data = ioread8(subdev->mmio + addr);
+ nv_spam(subdev, "nv_rd08 0x%06x 0x%02x\n", addr, data);
+ return data;
+}
+
+static inline u16
+nv_rd16(void *obj, u32 addr)
+{
+ struct nvkm_subdev *subdev = nv_subdev(obj);
+ u16 data = ioread16_native(subdev->mmio + addr);
+ nv_spam(subdev, "nv_rd16 0x%06x 0x%04x\n", addr, data);
+ return data;
+}
+
+static inline u32
+nv_rd32(void *obj, u32 addr)
+{
+ struct nvkm_subdev *subdev = nv_subdev(obj);
+ u32 data = ioread32_native(subdev->mmio + addr);
+ nv_spam(subdev, "nv_rd32 0x%06x 0x%08x\n", addr, data);
+ return data;
+}
+
+static inline void
+nv_wr08(void *obj, u32 addr, u8 data)
+{
+ struct nvkm_subdev *subdev = nv_subdev(obj);
+ nv_spam(subdev, "nv_wr08 0x%06x 0x%02x\n", addr, data);
+ iowrite8(data, subdev->mmio + addr);
+}
+
+static inline void
+nv_wr16(void *obj, u32 addr, u16 data)
+{
+ struct nvkm_subdev *subdev = nv_subdev(obj);
+ nv_spam(subdev, "nv_wr16 0x%06x 0x%04x\n", addr, data);
+ iowrite16_native(data, subdev->mmio + addr);
+}
+
+static inline void
+nv_wr32(void *obj, u32 addr, u32 data)
+{
+ struct nvkm_subdev *subdev = nv_subdev(obj);
+ nv_spam(subdev, "nv_wr32 0x%06x 0x%08x\n", addr, data);
+ iowrite32_native(data, subdev->mmio + addr);
+}
+
+static inline u32
+nv_mask(void *obj, u32 addr, u32 mask, u32 data)
+{
+ u32 temp = nv_rd32(obj, addr);
+ nv_wr32(obj, addr, (temp & ~mask) | data);
+ return temp;
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h
new file mode 100644
index 000000000..e489beef2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_BSP_H__
+#define __NVKM_BSP_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g84_bsp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
new file mode 100644
index 000000000..e832f729e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
@@ -0,0 +1,16 @@
+#ifndef __NVKM_CE_H__
+#define __NVKM_CE_H__
+#include <core/engine.h>
+
+void gt215_ce_intr(struct nvkm_subdev *);
+
+extern struct nvkm_oclass gt215_ce_oclass;
+extern struct nvkm_oclass gf100_ce0_oclass;
+extern struct nvkm_oclass gf100_ce1_oclass;
+extern struct nvkm_oclass gk104_ce0_oclass;
+extern struct nvkm_oclass gk104_ce1_oclass;
+extern struct nvkm_oclass gk104_ce2_oclass;
+extern struct nvkm_oclass gm204_ce0_oclass;
+extern struct nvkm_oclass gm204_ce1_oclass;
+extern struct nvkm_oclass gm204_ce2_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h
new file mode 100644
index 000000000..57c29e91b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_CIPHER_H__
+#define __NVKM_CIPHER_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g84_cipher_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/device.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/device.h
new file mode 100644
index 000000000..5d4805e67
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/device.h
@@ -0,0 +1,30 @@
+#ifndef __NOUVEAU_SUBDEV_DEVICE_H__
+#define __NOUVEAU_SUBDEV_DEVICE_H__
+
+#include <core/device.h>
+
+struct platform_device;
+
+enum nv_bus_type {
+ NOUVEAU_BUS_PCI,
+ NOUVEAU_BUS_PLATFORM,
+};
+
+#define nouveau_device_create(p,t,n,s,c,d,u) \
+ nouveau_device_create_((void *)(p), (t), (n), (s), (c), (d), \
+ sizeof(**u), (void **)u)
+
+int nouveau_device_create_(void *, enum nv_bus_type type, u64 name,
+ const char *sname, const char *cfg, const char *dbg,
+ int, void **);
+
+int nv04_identify(struct nouveau_device *);
+int nv10_identify(struct nouveau_device *);
+int nv20_identify(struct nouveau_device *);
+int nv30_identify(struct nouveau_device *);
+int nv40_identify(struct nouveau_device *);
+int nv50_identify(struct nouveau_device *);
+int nvc0_identify(struct nouveau_device *);
+int nve0_identify(struct nouveau_device *);
+int gm100_identify(struct nouveau_device *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
new file mode 100644
index 000000000..a5e1ed813
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_DISP_H__
+#define __NVKM_DISP_H__
+#include <core/engine.h>
+#include <core/event.h>
+
+struct nvkm_disp {
+ struct nvkm_engine base;
+
+ struct list_head outp;
+
+ struct nvkm_event hpd;
+ struct nvkm_event vblank;
+};
+
+static inline struct nvkm_disp *
+nvkm_disp(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_DISP);
+}
+
+extern struct nvkm_oclass *nv04_disp_oclass;
+extern struct nvkm_oclass *nv50_disp_oclass;
+extern struct nvkm_oclass *g84_disp_oclass;
+extern struct nvkm_oclass *gt200_disp_oclass;
+extern struct nvkm_oclass *g94_disp_oclass;
+extern struct nvkm_oclass *gt215_disp_oclass;
+extern struct nvkm_oclass *gf110_disp_oclass;
+extern struct nvkm_oclass *gk104_disp_oclass;
+extern struct nvkm_oclass *gk110_disp_oclass;
+extern struct nvkm_oclass *gm107_disp_oclass;
+extern struct nvkm_oclass *gm204_disp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h
new file mode 100644
index 000000000..c4fce8afc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h
@@ -0,0 +1,26 @@
+#ifndef __NVKM_DMAOBJ_H__
+#define __NVKM_DMAOBJ_H__
+#include <core/engine.h>
+struct nvkm_gpuobj;
+
+struct nvkm_dmaobj {
+ struct nvkm_object base;
+ u32 target;
+ u32 access;
+ u64 start;
+ u64 limit;
+};
+
+struct nvkm_dmaeng {
+ struct nvkm_engine base;
+
+ /* creates a "physical" dma object from a struct nvkm_dmaobj */
+ int (*bind)(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **);
+};
+
+extern struct nvkm_oclass *nv04_dmaeng_oclass;
+extern struct nvkm_oclass *nv50_dmaeng_oclass;
+extern struct nvkm_oclass *gf100_dmaeng_oclass;
+extern struct nvkm_oclass *gf110_dmaeng_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
new file mode 100644
index 000000000..bd38cf913
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
@@ -0,0 +1,81 @@
+#ifndef __NVKM_FALCON_H__
+#define __NVKM_FALCON_H__
+#include <core/engctx.h>
+
+struct nvkm_falcon_chan {
+ struct nvkm_engctx base;
+};
+
+#define nvkm_falcon_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nvkm_falcon_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_falcon_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_falcon_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_falcon_context_ctor _nvkm_engctx_ctor
+#define _nvkm_falcon_context_dtor _nvkm_engctx_dtor
+#define _nvkm_falcon_context_init _nvkm_engctx_init
+#define _nvkm_falcon_context_fini _nvkm_engctx_fini
+#define _nvkm_falcon_context_rd32 _nvkm_engctx_rd32
+#define _nvkm_falcon_context_wr32 _nvkm_engctx_wr32
+
+struct nvkm_falcon_data {
+ bool external;
+};
+
+#include <core/engine.h>
+
+struct nvkm_falcon {
+ struct nvkm_engine base;
+
+ u32 addr;
+ u8 version;
+ u8 secret;
+
+ struct nvkm_gpuobj *core;
+ bool external;
+
+ struct {
+ u32 limit;
+ u32 *data;
+ u32 size;
+ } code;
+
+ struct {
+ u32 limit;
+ u32 *data;
+ u32 size;
+ } data;
+};
+
+#define nv_falcon(priv) (&(priv)->base)
+
+#define nvkm_falcon_create(p,e,c,b,d,i,f,r) \
+ nvkm_falcon_create_((p), (e), (c), (b), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+#define nvkm_falcon_destroy(p) \
+ nvkm_engine_destroy(&(p)->base)
+#define nvkm_falcon_init(p) ({ \
+ struct nvkm_falcon *falcon = (p); \
+ _nvkm_falcon_init(nv_object(falcon)); \
+})
+#define nvkm_falcon_fini(p,s) ({ \
+ struct nvkm_falcon *falcon = (p); \
+ _nvkm_falcon_fini(nv_object(falcon), (s)); \
+})
+
+int nvkm_falcon_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32, bool, const char *,
+ const char *, int, void **);
+
+void nvkm_falcon_intr(struct nvkm_subdev *subdev);
+
+#define _nvkm_falcon_dtor _nvkm_engine_dtor
+int _nvkm_falcon_init(struct nvkm_object *);
+int _nvkm_falcon_fini(struct nvkm_object *, bool);
+u32 _nvkm_falcon_rd32(struct nvkm_object *, u64);
+void _nvkm_falcon_wr32(struct nvkm_object *, u64, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
new file mode 100644
index 000000000..97cdeab8e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
@@ -0,0 +1,127 @@
+#ifndef __NVKM_FIFO_H__
+#define __NVKM_FIFO_H__
+#include <core/namedb.h>
+
+struct nvkm_fifo_chan {
+ struct nvkm_namedb namedb;
+ struct nvkm_dmaobj *pushdma;
+ struct nvkm_gpuobj *pushgpu;
+ void __iomem *user;
+ u64 addr;
+ u32 size;
+ u16 chid;
+ atomic_t refcnt; /* NV04_NVSW_SET_REF */
+};
+
+static inline struct nvkm_fifo_chan *
+nvkm_fifo_chan(void *obj)
+{
+ return (void *)nv_namedb(obj);
+}
+
+#define nvkm_fifo_channel_create(p,e,c,b,a,s,n,m,d) \
+ nvkm_fifo_channel_create_((p), (e), (c), (b), (a), (s), (n), \
+ (m), sizeof(**d), (void **)d)
+#define nvkm_fifo_channel_init(p) \
+ nvkm_namedb_init(&(p)->namedb)
+#define nvkm_fifo_channel_fini(p,s) \
+ nvkm_namedb_fini(&(p)->namedb, (s))
+
+int nvkm_fifo_channel_create_(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *,
+ int bar, u32 addr, u32 size, u32 push,
+ u64 engmask, int len, void **);
+void nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *);
+
+#define _nvkm_fifo_channel_init _nvkm_namedb_init
+#define _nvkm_fifo_channel_fini _nvkm_namedb_fini
+
+void _nvkm_fifo_channel_dtor(struct nvkm_object *);
+int _nvkm_fifo_channel_map(struct nvkm_object *, u64 *, u32 *);
+u32 _nvkm_fifo_channel_rd32(struct nvkm_object *, u64);
+void _nvkm_fifo_channel_wr32(struct nvkm_object *, u64, u32);
+int _nvkm_fifo_channel_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
+
+#include <core/gpuobj.h>
+
+struct nvkm_fifo_base {
+ struct nvkm_gpuobj gpuobj;
+};
+
+#define nvkm_fifo_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_gpuobj_create((p), (e), (c), 0, (g), (s), (a), (f), (d))
+#define nvkm_fifo_context_destroy(p) \
+ nvkm_gpuobj_destroy(&(p)->gpuobj)
+#define nvkm_fifo_context_init(p) \
+ nvkm_gpuobj_init(&(p)->gpuobj)
+#define nvkm_fifo_context_fini(p,s) \
+ nvkm_gpuobj_fini(&(p)->gpuobj, (s))
+
+#define _nvkm_fifo_context_dtor _nvkm_gpuobj_dtor
+#define _nvkm_fifo_context_init _nvkm_gpuobj_init
+#define _nvkm_fifo_context_fini _nvkm_gpuobj_fini
+#define _nvkm_fifo_context_rd32 _nvkm_gpuobj_rd32
+#define _nvkm_fifo_context_wr32 _nvkm_gpuobj_wr32
+
+#include <core/engine.h>
+#include <core/event.h>
+
+struct nvkm_fifo {
+ struct nvkm_engine base;
+
+ struct nvkm_event cevent; /* channel creation event */
+ struct nvkm_event uevent; /* async user trigger */
+
+ struct nvkm_object **channel;
+ spinlock_t lock;
+ u16 min;
+ u16 max;
+
+ int (*chid)(struct nvkm_fifo *, struct nvkm_object *);
+ void (*pause)(struct nvkm_fifo *, unsigned long *);
+ void (*start)(struct nvkm_fifo *, unsigned long *);
+};
+
+static inline struct nvkm_fifo *
+nvkm_fifo(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_FIFO);
+}
+
+#define nvkm_fifo_create(o,e,c,fc,lc,d) \
+ nvkm_fifo_create_((o), (e), (c), (fc), (lc), sizeof(**d), (void **)d)
+#define nvkm_fifo_init(p) \
+ nvkm_engine_init(&(p)->base)
+#define nvkm_fifo_fini(p,s) \
+ nvkm_engine_fini(&(p)->base, (s))
+
+int nvkm_fifo_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int min, int max,
+ int size, void **);
+void nvkm_fifo_destroy(struct nvkm_fifo *);
+const char *
+nvkm_client_name_for_fifo_chid(struct nvkm_fifo *fifo, u32 chid);
+
+#define _nvkm_fifo_init _nvkm_engine_init
+#define _nvkm_fifo_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass *nv04_fifo_oclass;
+extern struct nvkm_oclass *nv10_fifo_oclass;
+extern struct nvkm_oclass *nv17_fifo_oclass;
+extern struct nvkm_oclass *nv40_fifo_oclass;
+extern struct nvkm_oclass *nv50_fifo_oclass;
+extern struct nvkm_oclass *g84_fifo_oclass;
+extern struct nvkm_oclass *gf100_fifo_oclass;
+extern struct nvkm_oclass *gk104_fifo_oclass;
+extern struct nvkm_oclass *gk20a_fifo_oclass;
+extern struct nvkm_oclass *gk208_fifo_oclass;
+extern struct nvkm_oclass *gm204_fifo_oclass;
+
+int nvkm_fifo_uevent_ctor(struct nvkm_object *, void *, u32,
+ struct nvkm_notify *);
+void nvkm_fifo_uevent(struct nvkm_fifo *);
+
+void nv04_fifo_intr(struct nvkm_subdev *);
+int nv04_fifo_context_attach(struct nvkm_object *, struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h
new file mode 100644
index 000000000..7cbe20280
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h
@@ -0,0 +1,88 @@
+#ifndef __NVKM_GR_H__
+#define __NVKM_GR_H__
+#include <core/engctx.h>
+
+struct nvkm_gr_chan {
+ struct nvkm_engctx base;
+};
+
+#define nvkm_gr_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nvkm_gr_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_gr_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_gr_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_gr_context_dtor _nvkm_engctx_dtor
+#define _nvkm_gr_context_init _nvkm_engctx_init
+#define _nvkm_gr_context_fini _nvkm_engctx_fini
+#define _nvkm_gr_context_rd32 _nvkm_engctx_rd32
+#define _nvkm_gr_context_wr32 _nvkm_engctx_wr32
+
+#include <core/engine.h>
+
+struct nvkm_gr {
+ struct nvkm_engine base;
+
+ /* Returns chipset-specific counts of units packed into an u64.
+ */
+ u64 (*units)(struct nvkm_gr *);
+};
+
+static inline struct nvkm_gr *
+nvkm_gr(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_GR);
+}
+
+#define nvkm_gr_create(p,e,c,y,d) \
+ nvkm_engine_create((p), (e), (c), (y), "PGRAPH", "graphics", (d))
+#define nvkm_gr_destroy(d) \
+ nvkm_engine_destroy(&(d)->base)
+#define nvkm_gr_init(d) \
+ nvkm_engine_init(&(d)->base)
+#define nvkm_gr_fini(d,s) \
+ nvkm_engine_fini(&(d)->base, (s))
+
+#define _nvkm_gr_dtor _nvkm_engine_dtor
+#define _nvkm_gr_init _nvkm_engine_init
+#define _nvkm_gr_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass nv04_gr_oclass;
+extern struct nvkm_oclass nv10_gr_oclass;
+extern struct nvkm_oclass nv20_gr_oclass;
+extern struct nvkm_oclass nv25_gr_oclass;
+extern struct nvkm_oclass nv2a_gr_oclass;
+extern struct nvkm_oclass nv30_gr_oclass;
+extern struct nvkm_oclass nv34_gr_oclass;
+extern struct nvkm_oclass nv35_gr_oclass;
+extern struct nvkm_oclass nv40_gr_oclass;
+extern struct nvkm_oclass nv50_gr_oclass;
+extern struct nvkm_oclass *gf100_gr_oclass;
+extern struct nvkm_oclass *gf108_gr_oclass;
+extern struct nvkm_oclass *gf104_gr_oclass;
+extern struct nvkm_oclass *gf110_gr_oclass;
+extern struct nvkm_oclass *gf117_gr_oclass;
+extern struct nvkm_oclass *gf119_gr_oclass;
+extern struct nvkm_oclass *gk104_gr_oclass;
+extern struct nvkm_oclass *gk20a_gr_oclass;
+extern struct nvkm_oclass *gk110_gr_oclass;
+extern struct nvkm_oclass *gk110b_gr_oclass;
+extern struct nvkm_oclass *gk208_gr_oclass;
+extern struct nvkm_oclass *gm107_gr_oclass;
+extern struct nvkm_oclass *gm204_gr_oclass;
+extern struct nvkm_oclass *gm206_gr_oclass;
+
+#include <core/enum.h>
+
+extern const struct nvkm_bitfield nv04_gr_nsource[];
+extern struct nvkm_ofuncs nv04_gr_ofuncs;
+bool nv04_gr_idle(void *obj);
+
+extern const struct nvkm_bitfield nv10_gr_intr_name[];
+extern const struct nvkm_bitfield nv10_gr_nstatus[];
+
+extern const struct nvkm_enum nv50_data_error_names[];
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h
new file mode 100644
index 000000000..4e500b398
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h
@@ -0,0 +1,62 @@
+#ifndef __NVKM_MPEG_H__
+#define __NVKM_MPEG_H__
+#include <core/engctx.h>
+
+struct nvkm_mpeg_chan {
+ struct nvkm_engctx base;
+};
+
+#define nvkm_mpeg_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nvkm_mpeg_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_mpeg_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_mpeg_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_mpeg_context_dtor _nvkm_engctx_dtor
+#define _nvkm_mpeg_context_init _nvkm_engctx_init
+#define _nvkm_mpeg_context_fini _nvkm_engctx_fini
+#define _nvkm_mpeg_context_rd32 _nvkm_engctx_rd32
+#define _nvkm_mpeg_context_wr32 _nvkm_engctx_wr32
+
+#include <core/engine.h>
+
+struct nvkm_mpeg {
+ struct nvkm_engine base;
+};
+
+#define nvkm_mpeg_create(p,e,c,d) \
+ nvkm_engine_create((p), (e), (c), true, "PMPEG", "mpeg", (d))
+#define nvkm_mpeg_destroy(d) \
+ nvkm_engine_destroy(&(d)->base)
+#define nvkm_mpeg_init(d) \
+ nvkm_engine_init(&(d)->base)
+#define nvkm_mpeg_fini(d,s) \
+ nvkm_engine_fini(&(d)->base, (s))
+
+#define _nvkm_mpeg_dtor _nvkm_engine_dtor
+#define _nvkm_mpeg_init _nvkm_engine_init
+#define _nvkm_mpeg_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass nv31_mpeg_oclass;
+extern struct nvkm_oclass nv40_mpeg_oclass;
+extern struct nvkm_oclass nv44_mpeg_oclass;
+extern struct nvkm_oclass nv50_mpeg_oclass;
+extern struct nvkm_oclass g84_mpeg_oclass;
+extern struct nvkm_ofuncs nv31_mpeg_ofuncs;
+extern struct nvkm_oclass nv31_mpeg_cclass;
+extern struct nvkm_oclass nv31_mpeg_sclass[];
+extern struct nvkm_oclass nv40_mpeg_sclass[];
+void nv31_mpeg_intr(struct nvkm_subdev *);
+void nv31_mpeg_tile_prog(struct nvkm_engine *, int);
+int nv31_mpeg_init(struct nvkm_object *);
+
+extern struct nvkm_ofuncs nv50_mpeg_ofuncs;
+int nv50_mpeg_context_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv50_mpeg_intr(struct nvkm_subdev *);
+int nv50_mpeg_init(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h
new file mode 100644
index 000000000..54b7672ee
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_MSPDEC_H__
+#define __NVKM_MSPDEC_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_mspdec_oclass;
+extern struct nvkm_oclass gf100_mspdec_oclass;
+extern struct nvkm_oclass gk104_mspdec_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h
new file mode 100644
index 000000000..c6c69d0a8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h
@@ -0,0 +1,6 @@
+#ifndef __NVKM_MSPPP_H__
+#define __NVKM_MSPPP_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_msppp_oclass;
+extern struct nvkm_oclass gf100_msppp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h
new file mode 100644
index 000000000..1f193b7bd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_MSVLD_H__
+#define __NVKM_MSVLD_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_msvld_oclass;
+extern struct nvkm_oclass gf100_msvld_oclass;
+extern struct nvkm_oclass gk104_msvld_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h
new file mode 100644
index 000000000..93181bbf0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_PM_H__
+#define __NVKM_PM_H__
+#include <core/engine.h>
+
+struct nvkm_perfdom;
+struct nvkm_perfctr;
+struct nvkm_pm {
+ struct nvkm_engine base;
+
+ struct nvkm_perfctx *context;
+ void *profile_data;
+
+ struct list_head domains;
+ u32 sequence;
+
+ /*XXX: temp for daemon backend */
+ u32 pwr[8];
+ u32 last;
+};
+
+static inline struct nvkm_pm *
+nvkm_pm(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_PM);
+}
+
+extern struct nvkm_oclass *nv40_pm_oclass;
+extern struct nvkm_oclass *nv50_pm_oclass;
+extern struct nvkm_oclass *g84_pm_oclass;
+extern struct nvkm_oclass *gt215_pm_oclass;
+extern struct nvkm_oclass gf100_pm_oclass;
+extern struct nvkm_oclass gk104_pm_oclass;
+extern struct nvkm_oclass gk110_pm_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h
new file mode 100644
index 000000000..44590a2a4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_SEC_H__
+#define __NVKM_SEC_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_sec_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h
new file mode 100644
index 000000000..a529013c9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h
@@ -0,0 +1,50 @@
+#ifndef __NVKM_SW_H__
+#define __NVKM_SW_H__
+#include <core/engctx.h>
+
+struct nvkm_sw_chan {
+ struct nvkm_engctx base;
+
+ int (*flip)(void *);
+ void *flip_data;
+};
+
+#define nvkm_sw_context_create(p,e,c,d) \
+ nvkm_engctx_create((p), (e), (c), (p), 0, 0, 0, (d))
+#define nvkm_sw_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_sw_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_sw_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_sw_context_dtor _nvkm_engctx_dtor
+#define _nvkm_sw_context_init _nvkm_engctx_init
+#define _nvkm_sw_context_fini _nvkm_engctx_fini
+
+#include <core/engine.h>
+
+struct nvkm_sw {
+ struct nvkm_engine base;
+};
+
+#define nvkm_sw_create(p,e,c,d) \
+ nvkm_engine_create((p), (e), (c), true, "SW", "software", (d))
+#define nvkm_sw_destroy(d) \
+ nvkm_engine_destroy(&(d)->base)
+#define nvkm_sw_init(d) \
+ nvkm_engine_init(&(d)->base)
+#define nvkm_sw_fini(d,s) \
+ nvkm_engine_fini(&(d)->base, (s))
+
+#define _nvkm_sw_dtor _nvkm_engine_dtor
+#define _nvkm_sw_init _nvkm_engine_init
+#define _nvkm_sw_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass *nv04_sw_oclass;
+extern struct nvkm_oclass *nv10_sw_oclass;
+extern struct nvkm_oclass *nv50_sw_oclass;
+extern struct nvkm_oclass *gf100_sw_oclass;
+
+void nv04_sw_intr(struct nvkm_subdev *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h
new file mode 100644
index 000000000..7851f18c5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_VP_H__
+#define __NVKM_VP_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g84_vp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h
new file mode 100644
index 000000000..7a216cca2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h
@@ -0,0 +1,35 @@
+#ifndef __NVKM_XTENSA_H__
+#define __NVKM_XTENSA_H__
+#include <core/engine.h>
+struct nvkm_gpuobj;
+
+struct nvkm_xtensa {
+ struct nvkm_engine base;
+
+ u32 addr;
+ struct nvkm_gpuobj *gpu_fw;
+ u32 fifo_val;
+ u32 unkd28;
+};
+
+#define nvkm_xtensa_create(p,e,c,b,d,i,f,r) \
+ nvkm_xtensa_create_((p), (e), (c), (b), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+
+int _nvkm_xtensa_engctx_ctor(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+void _nvkm_xtensa_intr(struct nvkm_subdev *);
+int nvkm_xtensa_create_(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *, u32, bool,
+ const char *, const char *,
+ int, void **);
+#define _nvkm_xtensa_dtor _nvkm_engine_dtor
+int _nvkm_xtensa_init(struct nvkm_object *);
+int _nvkm_xtensa_fini(struct nvkm_object *, bool);
+u32 _nvkm_xtensa_rd32(struct nvkm_object *, u64);
+void _nvkm_xtensa_wr32(struct nvkm_object *, u64, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
new file mode 100644
index 000000000..c7a007b8b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
@@ -0,0 +1,33 @@
+#ifndef __NVKM_BAR_H__
+#define __NVKM_BAR_H__
+#include <core/subdev.h>
+struct nvkm_mem;
+struct nvkm_vma;
+
+struct nvkm_bar {
+ struct nvkm_subdev base;
+
+ int (*alloc)(struct nvkm_bar *, struct nvkm_object *,
+ struct nvkm_mem *, struct nvkm_object **);
+
+ int (*kmap)(struct nvkm_bar *, struct nvkm_mem *, u32 flags,
+ struct nvkm_vma *);
+ int (*umap)(struct nvkm_bar *, struct nvkm_mem *, u32 flags,
+ struct nvkm_vma *);
+ void (*unmap)(struct nvkm_bar *, struct nvkm_vma *);
+ void (*flush)(struct nvkm_bar *);
+
+ /* whether the BAR supports to be ioremapped WC or should be uncached */
+ bool iomap_uncached;
+};
+
+static inline struct nvkm_bar *
+nvkm_bar(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_BAR);
+}
+
+extern struct nvkm_oclass nv50_bar_oclass;
+extern struct nvkm_oclass gf100_bar_oclass;
+extern struct nvkm_oclass gk20a_bar_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h
new file mode 100644
index 000000000..cef287e0b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_BIOS_H__
+#define __NVKM_BIOS_H__
+#include <core/subdev.h>
+
+struct nvkm_bios {
+ struct nvkm_subdev base;
+ u32 size;
+ u8 *data;
+
+ u32 bmp_offset;
+ u32 bit_offset;
+
+ struct {
+ u8 major;
+ u8 chip;
+ u8 minor;
+ u8 micro;
+ u8 patch;
+ } version;
+};
+
+static inline struct nvkm_bios *
+nvkm_bios(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_VBIOS);
+}
+
+u8 nvbios_checksum(const u8 *data, int size);
+u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
+
+extern struct nvkm_oclass nvkm_bios_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h
new file mode 100644
index 000000000..cf202c793
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h
@@ -0,0 +1,29 @@
+#ifndef __NVBIOS_M0203_H__
+#define __NVBIOS_M0203_H__
+struct nvbios_M0203T {
+#define M0203T_TYPE_RAMCFG 0x00
+ u8 type;
+ u16 pointer;
+};
+
+u32 nvbios_M0203Te(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_M0203Tp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_M0203T *);
+
+struct nvbios_M0203E {
+#define M0203E_TYPE_DDR2 0x0
+#define M0203E_TYPE_DDR3 0x1
+#define M0203E_TYPE_GDDR3 0x2
+#define M0203E_TYPE_GDDR5 0x3
+#define M0203E_TYPE_SKIP 0xf
+ u8 type;
+ u8 strap;
+ u8 group;
+};
+
+u32 nvbios_M0203Ee(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_M0203Ep(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_M0203E *);
+u32 nvbios_M0203Em(struct nvkm_bios *, u8 ramcfg, u8 *ver, u8 *hdr,
+ struct nvbios_M0203E *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h
new file mode 100644
index 000000000..d34608ff2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h
@@ -0,0 +1,29 @@
+#ifndef __NVBIOS_M0205_H__
+#define __NVBIOS_M0205_H__
+struct nvbios_M0205T {
+ u16 freq;
+};
+
+u32 nvbios_M0205Te(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+u32 nvbios_M0205Tp(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz,
+ struct nvbios_M0205T *);
+
+struct nvbios_M0205E {
+ u8 type;
+};
+
+u32 nvbios_M0205Ee(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_M0205Ep(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0205E *);
+
+struct nvbios_M0205S {
+ u8 data;
+};
+
+u32 nvbios_M0205Se(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_M0205Sp(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_M0205S *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h
new file mode 100644
index 000000000..c7ff8d952
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h
@@ -0,0 +1,27 @@
+#ifndef __NVBIOS_M0209_H__
+#define __NVBIOS_M0209_H__
+u32 nvbios_M0209Te(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+
+struct nvbios_M0209E {
+ u8 v00_40;
+ u8 bits;
+ u8 modulo;
+ u8 v02_40;
+ u8 v02_07;
+ u8 v03;
+};
+
+u32 nvbios_M0209Ee(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_M0209Ep(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0209E *);
+
+struct nvbios_M0209S {
+ u32 data[0x200];
+};
+
+u32 nvbios_M0209Se(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_M0209Sp(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_M0209S *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h
new file mode 100644
index 000000000..1c1c52eac
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_P0260_H__
+#define __NVBIOS_P0260_H__
+u32 nvbios_P0260Te(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
+
+struct nvbios_P0260E {
+ u32 data;
+};
+
+u32 nvbios_P0260Ee(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_P0260Ep(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_P0260E *);
+
+struct nvbios_P0260X {
+ u32 data;
+};
+
+u32 nvbios_P0260Xe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_P0260Xp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_P0260X *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h
new file mode 100644
index 000000000..6711732b7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h
@@ -0,0 +1,11 @@
+#ifndef __NVBIOS_BIT_H__
+#define __NVBIOS_BIT_H__
+struct bit_entry {
+ u8 id;
+ u8 version;
+ u16 length;
+ u16 offset;
+};
+
+int bit_entry(struct nvkm_bios *, u8 id, struct bit_entry *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h
new file mode 100644
index 000000000..4107aa546
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h
@@ -0,0 +1,37 @@
+#ifndef __NVBIOS_BMP_H__
+#define __NVBIOS_BMP_H__
+static inline u16
+bmp_version(struct nvkm_bios *bios)
+{
+ if (bios->bmp_offset) {
+ return nv_ro08(bios, bios->bmp_offset + 5) << 8 |
+ nv_ro08(bios, bios->bmp_offset + 6);
+ }
+
+ return 0x0000;
+}
+
+static inline u16
+bmp_mem_init_table(struct nvkm_bios *bios)
+{
+ if (bmp_version(bios) >= 0x0300)
+ return nv_ro16(bios, bios->bmp_offset + 24);
+ return 0x0000;
+}
+
+static inline u16
+bmp_sdr_seq_table(struct nvkm_bios *bios)
+{
+ if (bmp_version(bios) >= 0x0300)
+ return nv_ro16(bios, bios->bmp_offset + 26);
+ return 0x0000;
+}
+
+static inline u16
+bmp_ddr_seq_table(struct nvkm_bios *bios)
+{
+ if (bmp_version(bios) >= 0x0300)
+ return nv_ro16(bios, bios->bmp_offset + 28);
+ return 0x0000;
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h
new file mode 100644
index 000000000..934b0ae55
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h
@@ -0,0 +1,27 @@
+#ifndef __NVBIOS_BOOST_H__
+#define __NVBIOS_BOOST_H__
+u16 nvbios_boostTe(struct nvkm_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *);
+
+struct nvbios_boostE {
+ u8 pstate;
+ u32 min;
+ u32 max;
+};
+
+u16 nvbios_boostEe(struct nvkm_bios *, int idx, u8 *, u8 *, u8 *, u8 *);
+u16 nvbios_boostEp(struct nvkm_bios *, int idx, u8 *, u8 *, u8 *, u8 *,
+ struct nvbios_boostE *);
+u16 nvbios_boostEm(struct nvkm_bios *, u8, u8 *, u8 *, u8 *, u8 *,
+ struct nvbios_boostE *);
+
+struct nvbios_boostS {
+ u8 domain;
+ u8 percent;
+ u32 min;
+ u32 max;
+};
+
+u16 nvbios_boostSe(struct nvkm_bios *, int, u16, u8 *, u8 *, u8, u8);
+u16 nvbios_boostSp(struct nvkm_bios *, int, u16, u8 *, u8 *, u8, u8,
+ struct nvbios_boostS *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
new file mode 100644
index 000000000..e8e77ee24
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
@@ -0,0 +1,44 @@
+#ifndef __NVBIOS_CONN_H__
+#define __NVBIOS_CONN_H__
+enum dcb_connector_type {
+ DCB_CONNECTOR_VGA = 0x00,
+ DCB_CONNECTOR_TV_0 = 0x10,
+ DCB_CONNECTOR_TV_1 = 0x11,
+ DCB_CONNECTOR_TV_3 = 0x13,
+ DCB_CONNECTOR_DVI_I = 0x30,
+ DCB_CONNECTOR_DVI_D = 0x31,
+ DCB_CONNECTOR_DMS59_0 = 0x38,
+ DCB_CONNECTOR_DMS59_1 = 0x39,
+ DCB_CONNECTOR_LVDS = 0x40,
+ DCB_CONNECTOR_LVDS_SPWG = 0x41,
+ DCB_CONNECTOR_DP = 0x46,
+ DCB_CONNECTOR_eDP = 0x47,
+ DCB_CONNECTOR_HDMI_0 = 0x60,
+ DCB_CONNECTOR_HDMI_1 = 0x61,
+ DCB_CONNECTOR_HDMI_C = 0x63,
+ DCB_CONNECTOR_DMS59_DP0 = 0x64,
+ DCB_CONNECTOR_DMS59_DP1 = 0x65,
+ DCB_CONNECTOR_NONE = 0xff
+};
+
+struct nvbios_connT {
+};
+
+u32 nvbios_connTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_connTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_connT *info);
+
+struct nvbios_connE {
+ u8 type;
+ u8 location;
+ u8 hpd;
+ u8 dp;
+ u8 di;
+ u8 sr;
+ u8 lcdid;
+};
+
+u32 nvbios_connEe(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *hdr);
+u32 nvbios_connEp(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *hdr,
+ struct nvbios_connE *info);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h
new file mode 100644
index 000000000..2f0e0c8e8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h
@@ -0,0 +1,26 @@
+#ifndef __NVBIOS_CSTEP_H__
+#define __NVBIOS_CSTEP_H__
+u16 nvbios_cstepTe(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
+
+struct nvbios_cstepE {
+ u8 pstate;
+ u8 index;
+};
+
+u16 nvbios_cstepEe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u16 nvbios_cstepEp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_cstepE *);
+u16 nvbios_cstepEm(struct nvkm_bios *, u8 pstate, u8 *ver, u8 *hdr,
+ struct nvbios_cstepE *);
+
+struct nvbios_cstepX {
+ u32 freq;
+ u8 unkn[2];
+ u8 voltage;
+};
+
+u16 nvbios_cstepXe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u16 nvbios_cstepXp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_cstepX *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
new file mode 100644
index 000000000..4892a65dd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
@@ -0,0 +1,65 @@
+#ifndef __NVBIOS_DCB_H__
+#define __NVBIOS_DCB_H__
+enum dcb_output_type {
+ DCB_OUTPUT_ANALOG = 0x0,
+ DCB_OUTPUT_TV = 0x1,
+ DCB_OUTPUT_TMDS = 0x2,
+ DCB_OUTPUT_LVDS = 0x3,
+ DCB_OUTPUT_DP = 0x6,
+ DCB_OUTPUT_EOL = 0xe,
+ DCB_OUTPUT_UNUSED = 0xf,
+ DCB_OUTPUT_ANY = -1,
+};
+
+struct dcb_output {
+ int index; /* may not be raw dcb index if merging has happened */
+ u16 hasht;
+ u16 hashm;
+ enum dcb_output_type type;
+ uint8_t i2c_index;
+ uint8_t heads;
+ uint8_t connector;
+ uint8_t bus;
+ uint8_t location;
+ uint8_t or;
+ uint8_t link;
+ bool duallink_possible;
+ uint8_t extdev;
+ union {
+ struct sor_conf {
+ int link;
+ } sorconf;
+ struct {
+ int maxfreq;
+ } crtconf;
+ struct {
+ struct sor_conf sor;
+ bool use_straps_for_mode;
+ bool use_acpi_for_edid;
+ bool use_power_scripts;
+ } lvdsconf;
+ struct {
+ bool has_component_output;
+ } tvconf;
+ struct {
+ struct sor_conf sor;
+ int link_nr;
+ int link_bw;
+ } dpconf;
+ struct {
+ struct sor_conf sor;
+ int slave_addr;
+ } tmdsconf;
+ };
+ bool i2c_upper_default;
+};
+
+u16 dcb_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
+u16 dcb_outp(struct nvkm_bios *, u8 idx, u8 *ver, u8 *len);
+u16 dcb_outp_parse(struct nvkm_bios *, u8 idx, u8 *, u8 *,
+ struct dcb_output *);
+u16 dcb_outp_match(struct nvkm_bios *, u16 type, u16 mask, u8 *, u8 *,
+ struct dcb_output *);
+int dcb_outp_foreach(struct nvkm_bios *, void *data, int (*exec)
+ (struct nvkm_bios *, void *, int index, u16 entry));
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
new file mode 100644
index 000000000..db10c11f0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
@@ -0,0 +1,39 @@
+#ifndef __NVBIOS_DISP_H__
+#define __NVBIOS_DISP_H__
+u16 nvbios_disp_table(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub);
+
+struct nvbios_disp {
+ u16 data;
+};
+
+u16 nvbios_disp_entry(struct nvkm_bios *, u8 idx, u8 *ver, u8 *hdr, u8 *sub);
+u16 nvbios_disp_parse(struct nvkm_bios *, u8 idx, u8 *ver, u8 *hdr, u8 *sub,
+ struct nvbios_disp *);
+
+struct nvbios_outp {
+ u16 type;
+ u16 mask;
+ u16 script[3];
+};
+
+u16 nvbios_outp_entry(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_outp_parse(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
+u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
+
+struct nvbios_ocfg {
+ u16 match;
+ u16 clkcmp[2];
+};
+
+u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h
new file mode 100644
index 000000000..b4d39df70
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h
@@ -0,0 +1,31 @@
+#ifndef __NVBIOS_DP_H__
+#define __NVBIOS_DP_H__
+struct nvbios_dpout {
+ u16 type;
+ u16 mask;
+ u8 flags;
+ u32 script[5];
+ u32 lnkcmp;
+};
+
+u16 nvbios_dpout_parse(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_dpout *);
+u16 nvbios_dpout_match(struct nvkm_bios *, u16 type, u16 mask,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_dpout *);
+
+struct nvbios_dpcfg {
+ u8 pc;
+ u8 dc;
+ u8 pe;
+ u8 tx_pu;
+};
+
+u16
+nvbios_dpcfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *);
+u16
+nvbios_dpcfg_match(struct nvkm_bios *, u16 outp, u8 pc, u8 vs, u8 pe,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h
new file mode 100644
index 000000000..6d3bedc63
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h
@@ -0,0 +1,25 @@
+#ifndef __NVBIOS_EXTDEV_H__
+#define __NVBIOS_EXTDEV_H__
+enum nvbios_extdev_type {
+ NVBIOS_EXTDEV_LM89 = 0x02,
+ NVBIOS_EXTDEV_VT1103M = 0x40,
+ NVBIOS_EXTDEV_PX3540 = 0x41,
+ NVBIOS_EXTDEV_VT1105M = 0x42, /* or close enough... */
+ NVBIOS_EXTDEV_ADT7473 = 0x70, /* can also be a LM64 */
+ NVBIOS_EXTDEV_HDCP_EEPROM = 0x90,
+ NVBIOS_EXTDEV_NONE = 0xff,
+};
+
+struct nvbios_extdev_func {
+ u8 type;
+ u8 addr;
+ u8 bus;
+};
+
+int
+nvbios_extdev_parse(struct nvkm_bios *, int, struct nvbios_extdev_func *);
+
+int
+nvbios_extdev_find(struct nvkm_bios *, enum nvbios_extdev_type,
+ struct nvbios_extdev_func *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h
new file mode 100644
index 000000000..693ea7d9e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h
@@ -0,0 +1,6 @@
+#ifndef __NVBIOS_FAN_H__
+#define __NVBIOS_FAN_H__
+#include <subdev/bios/therm.h>
+
+u16 nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
new file mode 100644
index 000000000..33be260dd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -0,0 +1,46 @@
+#ifndef __NVBIOS_GPIO_H__
+#define __NVBIOS_GPIO_H__
+enum dcb_gpio_func_name {
+ DCB_GPIO_PANEL_POWER = 0x01,
+ DCB_GPIO_TVDAC0 = 0x0c,
+ DCB_GPIO_TVDAC1 = 0x2d,
+ DCB_GPIO_FAN = 0x09,
+ DCB_GPIO_FAN_SENSE = 0x3d,
+ DCB_GPIO_UNUSED = 0xff,
+ DCB_GPIO_VID0 = 0x04,
+ DCB_GPIO_VID1 = 0x05,
+ DCB_GPIO_VID2 = 0x06,
+ DCB_GPIO_VID3 = 0x1a,
+ DCB_GPIO_VID4 = 0x73,
+ DCB_GPIO_VID5 = 0x74,
+ DCB_GPIO_VID6 = 0x75,
+ DCB_GPIO_VID7 = 0x76,
+};
+
+#define DCB_GPIO_LOG_DIR 0x02
+#define DCB_GPIO_LOG_DIR_OUT 0x00
+#define DCB_GPIO_LOG_DIR_IN 0x02
+#define DCB_GPIO_LOG_VAL 0x01
+#define DCB_GPIO_LOG_VAL_LO 0x00
+#define DCB_GPIO_LOG_VAL_HI 0x01
+
+struct dcb_gpio_func {
+ u8 func;
+ u8 line;
+ u8 log[2];
+
+ /* so far, "param" seems to only have an influence on PWM-related
+ * GPIOs such as FAN_CONTROL and PANEL_BACKLIGHT_LEVEL.
+ * if param equals 1, hardware PWM is available
+ * if param equals 0, the host should toggle the GPIO itself
+ */
+ u8 param;
+};
+
+u16 dcb_gpio_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_gpio_entry(struct nvkm_bios *, int idx, int ent, u8 *ver, u8 *len);
+u16 dcb_gpio_parse(struct nvkm_bios *, int idx, int ent, u8 *ver, u8 *len,
+ struct dcb_gpio_func *);
+u16 dcb_gpio_match(struct nvkm_bios *, int idx, u8 func, u8 line,
+ u8 *ver, u8 *len, struct dcb_gpio_func *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h
new file mode 100644
index 000000000..85c529ecf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h
@@ -0,0 +1,25 @@
+#ifndef __NVBIOS_I2C_H__
+#define __NVBIOS_I2C_H__
+enum dcb_i2c_type {
+ /* matches bios type field prior to ccb 4.1 */
+ DCB_I2C_NV04_BIT = 0x00,
+ DCB_I2C_NV4E_BIT = 0x04,
+ DCB_I2C_NVIO_BIT = 0x05,
+ DCB_I2C_NVIO_AUX = 0x06,
+ /* made up - mostly */
+ DCB_I2C_PMGR = 0x80,
+ DCB_I2C_UNUSED = 0xff
+};
+
+struct dcb_i2c_entry {
+ enum dcb_i2c_type type;
+ u8 drive;
+ u8 sense;
+ u8 share;
+ u8 auxch;
+};
+
+u16 dcb_i2c_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_i2c_entry(struct nvkm_bios *, u8 index, u8 *ver, u8 *len);
+int dcb_i2c_parse(struct nvkm_bios *, u8 index, struct dcb_i2c_entry *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h
new file mode 100644
index 000000000..e15d63b9a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h
@@ -0,0 +1,11 @@
+#ifndef __NVBIOS_IMAGE_H__
+#define __NVBIOS_IMAGE_H__
+struct nvbios_image {
+ u32 base;
+ u32 size;
+ u8 type;
+ bool last;
+};
+
+bool nvbios_image(struct nvkm_bios *, int, struct nvbios_image *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h
new file mode 100644
index 000000000..578a667ee
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h
@@ -0,0 +1,20 @@
+#ifndef __NVBIOS_INIT_H__
+#define __NVBIOS_INIT_H__
+struct nvbios_init {
+ struct nvkm_subdev *subdev;
+ struct nvkm_bios *bios;
+ u16 offset;
+ struct dcb_output *outp;
+ int crtc;
+
+ /* internal state used during parsing */
+ u8 execute;
+ u32 nested;
+ u16 repeat;
+ u16 repend;
+ u32 ramcfg;
+};
+
+int nvbios_exec(struct nvbios_init *);
+int nvbios_init(struct nvkm_subdev *, bool execute);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h
new file mode 100644
index 000000000..4e31b64c5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h
@@ -0,0 +1,6 @@
+#ifndef __NVBIOS_MXM_H__
+#define __NVBIOS_MXM_H__
+u16 mxm_table(struct nvkm_bios *, u8 *ver, u8 *hdr);
+u8 mxm_sor_map(struct nvkm_bios *, u8 conn);
+u8 mxm_ddc_map(struct nvkm_bios *, u8 port);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h
new file mode 100644
index 000000000..64a59549b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h
@@ -0,0 +1,10 @@
+#ifndef __NVBIOS_NPDE_H__
+#define __NVBIOS_NPDE_H__
+struct nvbios_npdeT {
+ u32 image_size;
+ bool last;
+};
+
+u32 nvbios_npdeTe(struct nvkm_bios *, u32);
+u32 nvbios_npdeTp(struct nvkm_bios *, u32, struct nvbios_npdeT *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h
new file mode 100644
index 000000000..e85931541
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h
@@ -0,0 +1,16 @@
+#ifndef __NVBIOS_PCIR_H__
+#define __NVBIOS_PCIR_H__
+struct nvbios_pcirT {
+ u16 vendor_id;
+ u16 device_id;
+ u8 class_code[3];
+ u32 image_size;
+ u16 image_rev;
+ u8 image_type;
+ bool last;
+};
+
+u32 nvbios_pcirTe(struct nvkm_bios *, u32, u8 *ver, u16 *hdr);
+u32 nvbios_pcirTp(struct nvkm_bios *, u32, u8 *ver, u16 *hdr,
+ struct nvbios_pcirT *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
new file mode 100644
index 000000000..7cc2becab
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -0,0 +1,41 @@
+#ifndef __NVBIOS_PERF_H__
+#define __NVBIOS_PERF_H__
+u16 nvbios_perf_table(struct nvkm_bios *, u8 *ver, u8 *hdr,
+ u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+
+struct nvbios_perfE {
+ u8 pstate;
+ u8 fanspeed;
+ u8 voltage;
+ u32 core;
+ u32 shader;
+ u32 memory;
+ u32 vdec;
+ u32 disp;
+ u32 script;
+};
+
+u16 nvbios_perf_entry(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_perfEp(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_perfE *);
+
+struct nvbios_perfS {
+ union {
+ struct {
+ u32 freq;
+ } v40;
+ };
+};
+
+u32 nvbios_perfSe(struct nvkm_bios *, u32 data, int idx,
+ u8 *ver, u8 *hdr, u8 cnt, u8 len);
+u32 nvbios_perfSp(struct nvkm_bios *, u32 data, int idx,
+ u8 *ver, u8 *hdr, u8 cnt, u8 len, struct nvbios_perfS *);
+
+struct nvbios_perf_fan {
+ u32 pwm_divisor;
+};
+
+int nvbios_perf_fan_parse(struct nvkm_bios *, struct nvbios_perf_fan *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h
new file mode 100644
index 000000000..5a69978d1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h
@@ -0,0 +1,75 @@
+#ifndef __NVBIOS_PLL_H__
+#define __NVBIOS_PLL_H__
+/*XXX: kill me */
+struct nvkm_pll_vals {
+ union {
+ struct {
+#ifdef __BIG_ENDIAN
+ uint8_t N1, M1, N2, M2;
+#else
+ uint8_t M1, N1, M2, N2;
+#endif
+ };
+ struct {
+ uint16_t NM1, NM2;
+ } __attribute__((packed));
+ };
+ int log2P;
+
+ int refclk;
+};
+
+/* these match types in pll limits table version 0x40,
+ * nvkm uses them on all chipsets internally where a
+ * specific pll needs to be referenced, but the exact
+ * register isn't known.
+ */
+enum nvbios_pll_type {
+ PLL_CORE = 0x01,
+ PLL_SHADER = 0x02,
+ PLL_UNK03 = 0x03,
+ PLL_MEMORY = 0x04,
+ PLL_VDEC = 0x05,
+ PLL_UNK40 = 0x40,
+ PLL_UNK41 = 0x41,
+ PLL_UNK42 = 0x42,
+ PLL_VPLL0 = 0x80,
+ PLL_VPLL1 = 0x81,
+ PLL_VPLL2 = 0x82,
+ PLL_VPLL3 = 0x83,
+ PLL_MAX = 0xff
+};
+
+struct nvbios_pll {
+ enum nvbios_pll_type type;
+ u32 reg;
+ u32 refclk;
+
+ u8 min_p;
+ u8 max_p;
+ u8 bias_p;
+
+ /*
+ * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
+ * value) is no different to 6 (at least for vplls) so allowing the MNP
+ * calc to use 7 causes the generated clock to be out by a factor of 2.
+ * however, max_log2p cannot be fixed-up during parsing as the
+ * unmodified max_log2p value is still needed for setting mplls, hence
+ * an additional max_usable_log2p member
+ */
+ u8 max_p_usable;
+
+ struct {
+ u32 min_freq;
+ u32 max_freq;
+ u32 min_inputfreq;
+ u32 max_inputfreq;
+ u8 min_m;
+ u8 max_m;
+ u8 min_n;
+ u8 max_n;
+ } vco1, vco2;
+};
+
+int nvbios_pll_parse(struct nvkm_bios *, u32 type, struct nvbios_pll *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
new file mode 100644
index 000000000..d606875c1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
@@ -0,0 +1,35 @@
+#ifndef __NVBIOS_PMU_H__
+#define __NVBIOS_PMU_H__
+struct nvbios_pmuT {
+};
+
+u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_pmuTp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_pmuT *);
+
+struct nvbios_pmuE {
+ u8 type;
+ u32 data;
+};
+
+u32 nvbios_pmuEe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_pmuEp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_pmuE *);
+
+struct nvbios_pmuR {
+ u32 boot_addr_pmu;
+ u32 boot_addr;
+ u32 boot_size;
+ u32 code_addr_pmu;
+ u32 code_addr;
+ u32 code_size;
+ u32 init_addr_pmu;
+
+ u32 data_addr_pmu;
+ u32 data_addr;
+ u32 data_size;
+ u32 args_addr_pmu;
+};
+
+bool nvbios_pmuRm(struct nvkm_bios *, u8 type, struct nvbios_pmuR *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
new file mode 100644
index 000000000..420426793
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -0,0 +1,141 @@
+#ifndef __NVBIOS_RAMCFG_H__
+#define __NVBIOS_RAMCFG_H__
+struct nvbios_ramcfg {
+ unsigned rammap_ver;
+ unsigned rammap_hdr;
+ unsigned rammap_min;
+ unsigned rammap_max;
+ union {
+ struct {
+ unsigned rammap_10_04_02:1;
+ unsigned rammap_10_04_08:1;
+ };
+ struct {
+ unsigned rammap_11_08_01:1;
+ unsigned rammap_11_08_0c:2;
+ unsigned rammap_11_08_10:1;
+ unsigned rammap_11_09_01ff:9;
+ unsigned rammap_11_0a_03fe:9;
+ unsigned rammap_11_0a_0400:1;
+ unsigned rammap_11_0a_0800:1;
+ unsigned rammap_11_0b_01f0:5;
+ unsigned rammap_11_0b_0200:1;
+ unsigned rammap_11_0b_0400:1;
+ unsigned rammap_11_0b_0800:1;
+ unsigned rammap_11_0d:8;
+ unsigned rammap_11_0e:8;
+ unsigned rammap_11_0f:8;
+ unsigned rammap_11_11_0c:2;
+ };
+ };
+
+ unsigned ramcfg_ver;
+ unsigned ramcfg_hdr;
+ unsigned ramcfg_timing;
+ union {
+ struct {
+ unsigned ramcfg_10_02_01:1;
+ unsigned ramcfg_10_02_02:1;
+ unsigned ramcfg_10_02_04:1;
+ unsigned ramcfg_10_02_08:1;
+ unsigned ramcfg_10_02_10:1;
+ unsigned ramcfg_10_02_20:1;
+ unsigned ramcfg_10_DLLoff:1;
+ unsigned ramcfg_10_03_0f:4;
+ unsigned ramcfg_10_04_01:1;
+ unsigned ramcfg_10_05:8;
+ unsigned ramcfg_10_06:8;
+ unsigned ramcfg_10_07:8;
+ unsigned ramcfg_10_08:8;
+ unsigned ramcfg_10_09_0f:4;
+ unsigned ramcfg_10_09_f0:4;
+ };
+ struct {
+ unsigned ramcfg_11_01_01:1;
+ unsigned ramcfg_11_01_02:1;
+ unsigned ramcfg_11_01_04:1;
+ unsigned ramcfg_11_01_08:1;
+ unsigned ramcfg_11_01_10:1;
+ unsigned ramcfg_11_01_20:1;
+ unsigned ramcfg_11_01_40:1;
+ unsigned ramcfg_11_01_80:1;
+ unsigned ramcfg_11_02_03:2;
+ unsigned ramcfg_11_02_04:1;
+ unsigned ramcfg_11_02_08:1;
+ unsigned ramcfg_11_02_10:1;
+ unsigned ramcfg_11_02_40:1;
+ unsigned ramcfg_11_02_80:1;
+ unsigned ramcfg_11_03_0f:4;
+ unsigned ramcfg_11_03_30:2;
+ unsigned ramcfg_11_03_c0:2;
+ unsigned ramcfg_11_03_f0:4;
+ unsigned ramcfg_11_04:8;
+ unsigned ramcfg_11_06:8;
+ unsigned ramcfg_11_07_02:1;
+ unsigned ramcfg_11_07_04:1;
+ unsigned ramcfg_11_07_08:1;
+ unsigned ramcfg_11_07_10:1;
+ unsigned ramcfg_11_07_40:1;
+ unsigned ramcfg_11_07_80:1;
+ unsigned ramcfg_11_08_01:1;
+ unsigned ramcfg_11_08_02:1;
+ unsigned ramcfg_11_08_04:1;
+ unsigned ramcfg_11_08_08:1;
+ unsigned ramcfg_11_08_10:1;
+ unsigned ramcfg_11_08_20:1;
+ unsigned ramcfg_11_09:8;
+ };
+ };
+
+ unsigned timing_ver;
+ unsigned timing_hdr;
+ unsigned timing[11];
+ union {
+ struct {
+ unsigned timing_10_WR:8;
+ unsigned timing_10_WTR:8;
+ unsigned timing_10_CL:8;
+ unsigned timing_10_RC:8;
+ /*empty: 4 */
+ unsigned timing_10_RFC:8; /* Byte 5 */
+ /*empty: 6 */
+ unsigned timing_10_RAS:8; /* Byte 7 */
+ /*empty: 8 */
+ unsigned timing_10_RP:8; /* Byte 9 */
+ unsigned timing_10_RCDRD:8;
+ unsigned timing_10_RCDWR:8;
+ unsigned timing_10_RRD:8;
+ unsigned timing_10_13:8;
+ unsigned timing_10_ODT:3;
+ /* empty: 15 */
+ unsigned timing_10_16:8;
+ /* empty: 17 */
+ unsigned timing_10_18:8;
+ unsigned timing_10_CWL:8;
+ unsigned timing_10_20:8;
+ unsigned timing_10_21:8;
+ /* empty: 22, 23 */
+ unsigned timing_10_24:8;
+ };
+ struct {
+ unsigned timing_20_2e_03:2;
+ unsigned timing_20_2e_30:2;
+ unsigned timing_20_2e_c0:2;
+ unsigned timing_20_2f_03:2;
+ unsigned timing_20_2c_003f:6;
+ unsigned timing_20_2c_1fc0:7;
+ unsigned timing_20_30_f8:5;
+ unsigned timing_20_30_07:3;
+ unsigned timing_20_31_0007:3;
+ unsigned timing_20_31_0078:4;
+ unsigned timing_20_31_0780:4;
+ unsigned timing_20_31_0800:1;
+ unsigned timing_20_31_7000:3;
+ unsigned timing_20_31_8000:1;
+ };
+ };
+};
+
+u8 nvbios_ramcfg_count(struct nvkm_bios *);
+u8 nvbios_ramcfg_index(struct nvkm_subdev *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
new file mode 100644
index 000000000..609a905ec
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_RAMMAP_H__
+#define __NVBIOS_RAMMAP_H__
+#include <subdev/bios/ramcfg.h>
+
+u32 nvbios_rammapTe(struct nvkm_bios *, u8 *ver, u8 *hdr,
+ u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+
+u32 nvbios_rammapEe(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_rammapEp(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
+u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
+
+u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
+ u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
+ u8 *ver, u8 *hdr);
+u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
+ u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
+ u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h
new file mode 100644
index 000000000..dd3ba960e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h
@@ -0,0 +1,72 @@
+#ifndef __NVBIOS_THERM_H__
+#define __NVBIOS_THERM_H__
+struct nvbios_therm_threshold {
+ u8 temp;
+ u8 hysteresis;
+};
+
+struct nvbios_therm_sensor {
+ /* diode */
+ s16 slope_mult;
+ s16 slope_div;
+ s16 offset_num;
+ s16 offset_den;
+ s8 offset_constant;
+
+ /* thresholds */
+ struct nvbios_therm_threshold thrs_fan_boost;
+ struct nvbios_therm_threshold thrs_down_clock;
+ struct nvbios_therm_threshold thrs_critical;
+ struct nvbios_therm_threshold thrs_shutdown;
+};
+
+enum nvbios_therm_fan_type {
+ NVBIOS_THERM_FAN_UNK = 0,
+ NVBIOS_THERM_FAN_TOGGLE = 1,
+ NVBIOS_THERM_FAN_PWM = 2,
+};
+
+/* no vbios have more than 6 */
+#define NVKM_TEMP_FAN_TRIP_MAX 10
+struct nvbios_therm_trip_point {
+ int fan_duty;
+ int temp;
+ int hysteresis;
+};
+
+enum nvbios_therm_fan_mode {
+ NVBIOS_THERM_FAN_TRIP = 0,
+ NVBIOS_THERM_FAN_LINEAR = 1,
+ NVBIOS_THERM_FAN_OTHER = 2,
+};
+
+struct nvbios_therm_fan {
+ enum nvbios_therm_fan_type type;
+
+ u32 pwm_freq;
+
+ u8 min_duty;
+ u8 max_duty;
+
+ u16 bump_period;
+ u16 slow_down_period;
+
+ enum nvbios_therm_fan_mode fan_mode;
+ struct nvbios_therm_trip_point trip[NVKM_TEMP_FAN_TRIP_MAX];
+ u8 nr_fan_trip;
+ u8 linear_min_temp;
+ u8 linear_max_temp;
+};
+
+enum nvbios_therm_domain {
+ NVBIOS_THERM_DOMAIN_CORE,
+ NVBIOS_THERM_DOMAIN_AMBIENT,
+};
+
+int
+nvbios_therm_sensor_parse(struct nvkm_bios *, enum nvbios_therm_domain,
+ struct nvbios_therm_sensor *);
+
+int
+nvbios_therm_fan_parse(struct nvkm_bios *, struct nvbios_therm_fan *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h
new file mode 100644
index 000000000..339a826aa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h
@@ -0,0 +1,11 @@
+#ifndef __NVBIOS_TIMING_H__
+#define __NVBIOS_TIMING_H__
+#include <subdev/bios/ramcfg.h>
+
+u16 nvbios_timingTe(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+u16 nvbios_timingEe(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_timingEp(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h
new file mode 100644
index 000000000..6633c6db9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_VMAP_H__
+#define __NVBIOS_VMAP_H__
+struct nvbios_vmap {
+};
+
+u16 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_vmap_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_vmap *);
+
+struct nvbios_vmap_entry {
+ u8 unk0;
+ u8 link;
+ u32 min;
+ u32 max;
+ s32 arg[6];
+};
+
+u16 nvbios_vmap_entry(struct nvkm_bios *, int idx, u8 *ver, u8 *len);
+u16 nvbios_vmap_entry_parse(struct nvkm_bios *, int idx, u8 *ver, u8 *len,
+ struct nvbios_vmap_entry *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
new file mode 100644
index 000000000..eb2de4b85
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
@@ -0,0 +1,23 @@
+#ifndef __NVBIOS_VOLT_H__
+#define __NVBIOS_VOLT_H__
+struct nvbios_volt {
+ u8 vidmask;
+ u32 min;
+ u32 max;
+ u32 base;
+ s16 step;
+};
+
+u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_volt_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_volt *);
+
+struct nvbios_volt_entry {
+ u32 voltage;
+ u8 vid;
+};
+
+u16 nvbios_volt_entry(struct nvkm_bios *, int idx, u8 *ver, u8 *len);
+u16 nvbios_volt_entry_parse(struct nvkm_bios *, int idx, u8 *ver, u8 *len,
+ struct nvbios_volt_entry *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h
new file mode 100644
index 000000000..0c0fe234f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h
@@ -0,0 +1,18 @@
+#ifndef __NVBIOS_XPIO_H__
+#define __NVBIOS_XPIO_H__
+
+#define NVBIOS_XPIO_FLAG_AUX 0x10
+#define NVBIOS_XPIO_FLAG_AUX0 0x00
+#define NVBIOS_XPIO_FLAG_AUX1 0x10
+
+struct nvbios_xpio {
+ u8 type;
+ u8 addr;
+ u8 flags;
+};
+
+u16 dcb_xpio_table(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_xpio_parse(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
new file mode 100644
index 000000000..fba83c048
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
@@ -0,0 +1,50 @@
+#ifndef __NVKM_BUS_H__
+#define __NVKM_BUS_H__
+#include <core/subdev.h>
+
+struct nvkm_bus_intr {
+ u32 stat;
+ u32 unit;
+};
+
+struct nvkm_bus {
+ struct nvkm_subdev base;
+ int (*hwsq_exec)(struct nvkm_bus *, u32 *, u32);
+ u32 hwsq_size;
+};
+
+static inline struct nvkm_bus *
+nvkm_bus(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_BUS);
+}
+
+#define nvkm_bus_create(p, e, o, d) \
+ nvkm_subdev_create_((p), (e), (o), 0, "PBUS", "master", \
+ sizeof(**d), (void **)d)
+#define nvkm_bus_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_bus_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_bus_fini(p, s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+#define _nvkm_bus_dtor _nvkm_subdev_dtor
+#define _nvkm_bus_init _nvkm_subdev_init
+#define _nvkm_bus_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass *nv04_bus_oclass;
+extern struct nvkm_oclass *nv31_bus_oclass;
+extern struct nvkm_oclass *nv50_bus_oclass;
+extern struct nvkm_oclass *g94_bus_oclass;
+extern struct nvkm_oclass *gf100_bus_oclass;
+
+/* interface to sequencer */
+struct nvkm_hwsq;
+int nvkm_hwsq_init(struct nvkm_bus *, struct nvkm_hwsq **);
+int nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec);
+void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data);
+void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data);
+void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
+void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h
new file mode 100644
index 000000000..f5d303850
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h
@@ -0,0 +1,161 @@
+#ifndef __NVKM_CLK_H__
+#define __NVKM_CLK_H__
+#include <core/subdev.h>
+#include <core/notify.h>
+struct nvbios_pll;
+struct nvkm_pll_vals;
+
+enum nv_clk_src {
+ nv_clk_src_crystal,
+ nv_clk_src_href,
+
+ nv_clk_src_hclk,
+ nv_clk_src_hclkm3,
+ nv_clk_src_hclkm3d2,
+ nv_clk_src_hclkm2d3, /* NVAA */
+ nv_clk_src_hclkm4, /* NVAA */
+ nv_clk_src_cclk, /* NVAA */
+
+ nv_clk_src_host,
+
+ nv_clk_src_sppll0,
+ nv_clk_src_sppll1,
+
+ nv_clk_src_mpllsrcref,
+ nv_clk_src_mpllsrc,
+ nv_clk_src_mpll,
+ nv_clk_src_mdiv,
+
+ nv_clk_src_core,
+ nv_clk_src_core_intm,
+ nv_clk_src_shader,
+
+ nv_clk_src_mem,
+
+ nv_clk_src_gpc,
+ nv_clk_src_rop,
+ nv_clk_src_hubk01,
+ nv_clk_src_hubk06,
+ nv_clk_src_hubk07,
+ nv_clk_src_copy,
+ nv_clk_src_daemon,
+ nv_clk_src_disp,
+ nv_clk_src_vdec,
+
+ nv_clk_src_dom6,
+
+ nv_clk_src_max,
+};
+
+struct nvkm_cstate {
+ struct list_head head;
+ u8 voltage;
+ u32 domain[nv_clk_src_max];
+};
+
+struct nvkm_pstate {
+ struct list_head head;
+ struct list_head list; /* c-states */
+ struct nvkm_cstate base;
+ u8 pstate;
+ u8 fanspeed;
+};
+
+struct nvkm_domain {
+ enum nv_clk_src name;
+ u8 bios; /* 0xff for none */
+#define NVKM_CLK_DOM_FLAG_CORE 0x01
+ u8 flags;
+ const char *mname;
+ int mdiv;
+};
+
+struct nvkm_clk {
+ struct nvkm_subdev base;
+
+ struct nvkm_domain *domains;
+ struct nvkm_pstate bstate;
+
+ struct list_head states;
+ int state_nr;
+
+ struct work_struct work;
+ wait_queue_head_t wait;
+ atomic_t waiting;
+
+ struct nvkm_notify pwrsrc_ntfy;
+ int pwrsrc;
+ int pstate; /* current */
+ int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
+ int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
+ int astate; /* perfmon adjustment (base) */
+ int tstate; /* thermal adjustment (max-) */
+ int dstate; /* display adjustment (min+) */
+
+ bool allow_reclock;
+
+ int (*read)(struct nvkm_clk *, enum nv_clk_src);
+ int (*calc)(struct nvkm_clk *, struct nvkm_cstate *);
+ int (*prog)(struct nvkm_clk *);
+ void (*tidy)(struct nvkm_clk *);
+
+ /*XXX: die, these are here *only* to support the completely
+ * bat-shit insane what-was-nvkm_hw.c code
+ */
+ int (*pll_calc)(struct nvkm_clk *, struct nvbios_pll *, int clk,
+ struct nvkm_pll_vals *pv);
+ int (*pll_prog)(struct nvkm_clk *, u32 reg1, struct nvkm_pll_vals *pv);
+};
+
+static inline struct nvkm_clk *
+nvkm_clk(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_CLK);
+}
+
+#define nvkm_clk_create(p,e,o,i,r,s,n,d) \
+ nvkm_clk_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d), \
+ (void **)d)
+#define nvkm_clk_destroy(p) ({ \
+ struct nvkm_clk *clk = (p); \
+ _nvkm_clk_dtor(nv_object(clk)); \
+})
+#define nvkm_clk_init(p) ({ \
+ struct nvkm_clk *clk = (p); \
+ _nvkm_clk_init(nv_object(clk)); \
+})
+#define nvkm_clk_fini(p,s) ({ \
+ struct nvkm_clk *clk = (p); \
+ _nvkm_clk_fini(nv_object(clk), (s)); \
+})
+
+int nvkm_clk_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *,
+ struct nvkm_domain *, struct nvkm_pstate *,
+ int, bool, int, void **);
+void _nvkm_clk_dtor(struct nvkm_object *);
+int _nvkm_clk_init(struct nvkm_object *);
+int _nvkm_clk_fini(struct nvkm_object *, bool);
+
+extern struct nvkm_oclass nv04_clk_oclass;
+extern struct nvkm_oclass nv40_clk_oclass;
+extern struct nvkm_oclass *nv50_clk_oclass;
+extern struct nvkm_oclass *g84_clk_oclass;
+extern struct nvkm_oclass *mcp77_clk_oclass;
+extern struct nvkm_oclass gt215_clk_oclass;
+extern struct nvkm_oclass gf100_clk_oclass;
+extern struct nvkm_oclass gk104_clk_oclass;
+extern struct nvkm_oclass gk20a_clk_oclass;
+
+int nv04_clk_pll_set(struct nvkm_clk *, u32 type, u32 freq);
+int nv04_clk_pll_calc(struct nvkm_clk *, struct nvbios_pll *, int clk,
+ struct nvkm_pll_vals *);
+int nv04_clk_pll_prog(struct nvkm_clk *, u32 reg1, struct nvkm_pll_vals *);
+int gt215_clk_pll_calc(struct nvkm_clk *, struct nvbios_pll *,
+ int clk, struct nvkm_pll_vals *);
+
+int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
+int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
+int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
+int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
new file mode 100644
index 000000000..d1bbe0d62
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_DEVINIT_H__
+#define __NVKM_DEVINIT_H__
+#include <core/subdev.h>
+
+struct nvkm_devinit {
+ struct nvkm_subdev base;
+ bool post;
+ void (*meminit)(struct nvkm_devinit *);
+ int (*pll_set)(struct nvkm_devinit *, u32 type, u32 freq);
+ u32 (*mmio)(struct nvkm_devinit *, u32 addr);
+};
+
+static inline struct nvkm_devinit *
+nvkm_devinit(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_DEVINIT);
+}
+
+extern struct nvkm_oclass *nv04_devinit_oclass;
+extern struct nvkm_oclass *nv05_devinit_oclass;
+extern struct nvkm_oclass *nv10_devinit_oclass;
+extern struct nvkm_oclass *nv1a_devinit_oclass;
+extern struct nvkm_oclass *nv20_devinit_oclass;
+extern struct nvkm_oclass *nv50_devinit_oclass;
+extern struct nvkm_oclass *g84_devinit_oclass;
+extern struct nvkm_oclass *g98_devinit_oclass;
+extern struct nvkm_oclass *gt215_devinit_oclass;
+extern struct nvkm_oclass *mcp89_devinit_oclass;
+extern struct nvkm_oclass *gf100_devinit_oclass;
+extern struct nvkm_oclass *gm107_devinit_oclass;
+extern struct nvkm_oclass *gm204_devinit_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
new file mode 100644
index 000000000..16da56cf4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
@@ -0,0 +1,154 @@
+#ifndef __NVKM_FB_H__
+#define __NVKM_FB_H__
+#include <core/subdev.h>
+
+#include <subdev/mmu.h>
+
+/* memory type/access flags, do not match hardware values */
+#define NV_MEM_ACCESS_RO 1
+#define NV_MEM_ACCESS_WO 2
+#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
+#define NV_MEM_ACCESS_SYS 4
+#define NV_MEM_ACCESS_VM 8
+#define NV_MEM_ACCESS_NOSNOOP 16
+
+#define NV_MEM_TARGET_VRAM 0
+#define NV_MEM_TARGET_PCI 1
+#define NV_MEM_TARGET_PCI_NOSNOOP 2
+#define NV_MEM_TARGET_VM 3
+#define NV_MEM_TARGET_GART 4
+
+#define NV_MEM_TYPE_VM 0x7f
+#define NV_MEM_COMP_VM 0x03
+
+struct nvkm_mem {
+ struct drm_device *dev;
+
+ struct nvkm_vma bar_vma;
+ struct nvkm_vma vma[2];
+ u8 page_shift;
+
+ struct nvkm_mm_node *tag;
+ struct list_head regions;
+ dma_addr_t *pages;
+ u32 memtype;
+ u64 offset;
+ u64 size;
+ struct sg_table *sg;
+};
+
+struct nvkm_fb_tile {
+ struct nvkm_mm_node *tag;
+ u32 addr;
+ u32 limit;
+ u32 pitch;
+ u32 zcomp;
+};
+
+struct nvkm_fb {
+ struct nvkm_subdev base;
+
+ bool (*memtype_valid)(struct nvkm_fb *, u32 memtype);
+
+ struct nvkm_ram *ram;
+
+ struct nvkm_mm vram;
+ struct nvkm_mm tags;
+
+ struct {
+ struct nvkm_fb_tile region[16];
+ int regions;
+ void (*init)(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+ void (*comp)(struct nvkm_fb *, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *);
+ void (*fini)(struct nvkm_fb *, int i, struct nvkm_fb_tile *);
+ void (*prog)(struct nvkm_fb *, int i, struct nvkm_fb_tile *);
+ } tile;
+};
+
+static inline struct nvkm_fb *
+nvkm_fb(void *obj)
+{
+ /* fbram uses this before device subdev pointer is valid */
+ if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
+ nv_subidx(obj) == NVDEV_SUBDEV_FB)
+ return obj;
+
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_FB);
+}
+
+extern struct nvkm_oclass *nv04_fb_oclass;
+extern struct nvkm_oclass *nv10_fb_oclass;
+extern struct nvkm_oclass *nv1a_fb_oclass;
+extern struct nvkm_oclass *nv20_fb_oclass;
+extern struct nvkm_oclass *nv25_fb_oclass;
+extern struct nvkm_oclass *nv30_fb_oclass;
+extern struct nvkm_oclass *nv35_fb_oclass;
+extern struct nvkm_oclass *nv36_fb_oclass;
+extern struct nvkm_oclass *nv40_fb_oclass;
+extern struct nvkm_oclass *nv41_fb_oclass;
+extern struct nvkm_oclass *nv44_fb_oclass;
+extern struct nvkm_oclass *nv46_fb_oclass;
+extern struct nvkm_oclass *nv47_fb_oclass;
+extern struct nvkm_oclass *nv49_fb_oclass;
+extern struct nvkm_oclass *nv4e_fb_oclass;
+extern struct nvkm_oclass *nv50_fb_oclass;
+extern struct nvkm_oclass *g84_fb_oclass;
+extern struct nvkm_oclass *gt215_fb_oclass;
+extern struct nvkm_oclass *mcp77_fb_oclass;
+extern struct nvkm_oclass *mcp89_fb_oclass;
+extern struct nvkm_oclass *gf100_fb_oclass;
+extern struct nvkm_oclass *gk104_fb_oclass;
+extern struct nvkm_oclass *gk20a_fb_oclass;
+extern struct nvkm_oclass *gm107_fb_oclass;
+
+#include <subdev/bios.h>
+#include <subdev/bios/ramcfg.h>
+
+struct nvkm_ram_data {
+ struct list_head head;
+ struct nvbios_ramcfg bios;
+ u32 freq;
+};
+
+struct nvkm_ram {
+ struct nvkm_object base;
+ enum {
+ NV_MEM_TYPE_UNKNOWN = 0,
+ NV_MEM_TYPE_STOLEN,
+ NV_MEM_TYPE_SGRAM,
+ NV_MEM_TYPE_SDRAM,
+ NV_MEM_TYPE_DDR1,
+ NV_MEM_TYPE_DDR2,
+ NV_MEM_TYPE_DDR3,
+ NV_MEM_TYPE_GDDR2,
+ NV_MEM_TYPE_GDDR3,
+ NV_MEM_TYPE_GDDR4,
+ NV_MEM_TYPE_GDDR5
+ } type;
+ u64 stolen;
+ u64 size;
+ u32 tags;
+
+ int ranks;
+ int parts;
+ int part_mask;
+
+ int (*get)(struct nvkm_fb *, u64 size, u32 align, u32 size_nc,
+ u32 type, struct nvkm_mem **);
+ void (*put)(struct nvkm_fb *, struct nvkm_mem **);
+
+ int (*calc)(struct nvkm_fb *, u32 freq);
+ int (*prog)(struct nvkm_fb *);
+ void (*tidy)(struct nvkm_fb *);
+ u32 freq;
+ u32 mr[16];
+ u32 mr1_nuts;
+
+ struct nvkm_ram_data *next;
+ struct nvkm_ram_data former;
+ struct nvkm_ram_data xition;
+ struct nvkm_ram_data target;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h
new file mode 100644
index 000000000..a1384786a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_FUSE_H__
+#define __NVKM_FUSE_H__
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nvkm_fuse {
+ struct nvkm_subdev base;
+};
+
+static inline struct nvkm_fuse *
+nvkm_fuse(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_FUSE);
+}
+
+#define nvkm_fuse_create(p, e, o, d) \
+ nvkm_fuse_create_((p), (e), (o), sizeof(**d), (void **)d)
+
+int nvkm_fuse_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_fuse_dtor(struct nvkm_object *);
+int _nvkm_fuse_init(struct nvkm_object *);
+#define _nvkm_fuse_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv50_fuse_oclass;
+extern struct nvkm_oclass gf100_fuse_oclass;
+extern struct nvkm_oclass gm107_fuse_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h
new file mode 100644
index 000000000..ca5099a81
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h
@@ -0,0 +1,44 @@
+#ifndef __NVKM_GPIO_H__
+#define __NVKM_GPIO_H__
+#include <core/subdev.h>
+#include <core/event.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/gpio.h>
+
+struct nvkm_gpio_ntfy_req {
+#define NVKM_GPIO_HI 0x01
+#define NVKM_GPIO_LO 0x02
+#define NVKM_GPIO_TOGGLED 0x03
+ u8 mask;
+ u8 line;
+};
+
+struct nvkm_gpio_ntfy_rep {
+ u8 mask;
+};
+
+struct nvkm_gpio {
+ struct nvkm_subdev base;
+
+ struct nvkm_event event;
+
+ void (*reset)(struct nvkm_gpio *, u8 func);
+ int (*find)(struct nvkm_gpio *, int idx, u8 tag, u8 line,
+ struct dcb_gpio_func *);
+ int (*set)(struct nvkm_gpio *, int idx, u8 tag, u8 line, int state);
+ int (*get)(struct nvkm_gpio *, int idx, u8 tag, u8 line);
+};
+
+static inline struct nvkm_gpio *
+nvkm_gpio(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_GPIO);
+}
+
+extern struct nvkm_oclass *nv10_gpio_oclass;
+extern struct nvkm_oclass *nv50_gpio_oclass;
+extern struct nvkm_oclass *g94_gpio_oclass;
+extern struct nvkm_oclass *gf110_gpio_oclass;
+extern struct nvkm_oclass *gk104_gpio_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
new file mode 100644
index 000000000..a2e33730f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
@@ -0,0 +1,135 @@
+#ifndef __NVKM_I2C_H__
+#define __NVKM_I2C_H__
+#include <core/subdev.h>
+#include <core/event.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/i2c.h>
+
+#define NV_I2C_PORT(n) (0x00 + (n))
+#define NV_I2C_AUX(n) (0x10 + (n))
+#define NV_I2C_EXT(n) (0x20 + (n))
+#define NV_I2C_DEFAULT(n) (0x80 + (n))
+
+#define NV_I2C_TYPE_DCBI2C(n) (0x0000 | (n))
+#define NV_I2C_TYPE_EXTDDC(e) (0x0005 | (e) << 8)
+#define NV_I2C_TYPE_EXTAUX(e) (0x0006 | (e) << 8)
+
+struct nvkm_i2c_ntfy_req {
+#define NVKM_I2C_PLUG 0x01
+#define NVKM_I2C_UNPLUG 0x02
+#define NVKM_I2C_IRQ 0x04
+#define NVKM_I2C_DONE 0x08
+#define NVKM_I2C_ANY 0x0f
+ u8 mask;
+ u8 port;
+};
+
+struct nvkm_i2c_ntfy_rep {
+ u8 mask;
+};
+
+struct nvkm_i2c_port {
+ struct nvkm_object base;
+ struct i2c_adapter adapter;
+ struct mutex mutex;
+
+ struct list_head head;
+ u8 index;
+ int aux;
+
+ const struct nvkm_i2c_func *func;
+};
+
+struct nvkm_i2c_func {
+ void (*drive_scl)(struct nvkm_i2c_port *, int);
+ void (*drive_sda)(struct nvkm_i2c_port *, int);
+ int (*sense_scl)(struct nvkm_i2c_port *);
+ int (*sense_sda)(struct nvkm_i2c_port *);
+
+ int (*aux)(struct nvkm_i2c_port *, bool, u8, u32, u8 *, u8);
+ int (*pattern)(struct nvkm_i2c_port *, int pattern);
+ int (*lnk_ctl)(struct nvkm_i2c_port *, int nr, int bw, bool enh);
+ int (*drv_ctl)(struct nvkm_i2c_port *, int lane, int sw, int pe);
+};
+
+struct nvkm_i2c_board_info {
+ struct i2c_board_info dev;
+ u8 udelay; /* set to 0 to use the standard delay */
+};
+
+struct nvkm_i2c {
+ struct nvkm_subdev base;
+ struct nvkm_event event;
+
+ struct nvkm_i2c_port *(*find)(struct nvkm_i2c *, u8 index);
+ struct nvkm_i2c_port *(*find_type)(struct nvkm_i2c *, u16 type);
+ int (*acquire_pad)(struct nvkm_i2c_port *, unsigned long timeout);
+ void (*release_pad)(struct nvkm_i2c_port *);
+ int (*acquire)(struct nvkm_i2c_port *, unsigned long timeout);
+ void (*release)(struct nvkm_i2c_port *);
+ int (*identify)(struct nvkm_i2c *, int index,
+ const char *what, struct nvkm_i2c_board_info *,
+ bool (*match)(struct nvkm_i2c_port *,
+ struct i2c_board_info *, void *),
+ void *);
+
+ wait_queue_head_t wait;
+ struct list_head ports;
+};
+
+static inline struct nvkm_i2c *
+nvkm_i2c(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_I2C);
+}
+
+extern struct nvkm_oclass *nv04_i2c_oclass;
+extern struct nvkm_oclass *nv4e_i2c_oclass;
+extern struct nvkm_oclass *nv50_i2c_oclass;
+extern struct nvkm_oclass *g94_i2c_oclass;
+extern struct nvkm_oclass *gf110_i2c_oclass;
+extern struct nvkm_oclass *gf117_i2c_oclass;
+extern struct nvkm_oclass *gk104_i2c_oclass;
+extern struct nvkm_oclass *gm204_i2c_oclass;
+
+static inline int
+nv_rdi2cr(struct nvkm_i2c_port *port, u8 addr, u8 reg)
+{
+ u8 val;
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 1, .buf = &reg },
+ { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
+ };
+
+ int ret = i2c_transfer(&port->adapter, msgs, 2);
+ if (ret != 2)
+ return -EIO;
+
+ return val;
+}
+
+static inline int
+nv_wri2cr(struct nvkm_i2c_port *port, u8 addr, u8 reg, u8 val)
+{
+ u8 buf[2] = { reg, val };
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 2, .buf = buf },
+ };
+
+ int ret = i2c_transfer(&port->adapter, msgs, 1);
+ if (ret != 1)
+ return -EIO;
+
+ return 0;
+}
+
+static inline bool
+nv_probe_i2c(struct nvkm_i2c_port *port, u8 addr)
+{
+ return nv_rdi2cr(port, addr, 0) >= 0;
+}
+
+int nv_rdaux(struct nvkm_i2c_port *, u32 addr, u8 *data, u8 size);
+int nv_wraux(struct nvkm_i2c_port *, u32 addr, u8 *data, u8 size);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
new file mode 100644
index 000000000..2150d8af0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_IBUS_H__
+#define __NVKM_IBUS_H__
+#include <core/subdev.h>
+
+struct nvkm_ibus {
+ struct nvkm_subdev base;
+};
+
+static inline struct nvkm_ibus *
+nvkm_ibus(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_IBUS);
+}
+
+#define nvkm_ibus_create(p,e,o,d) \
+ nvkm_subdev_create_((p), (e), (o), 0, "PIBUS", "ibus", \
+ sizeof(**d), (void **)d)
+#define nvkm_ibus_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_ibus_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_ibus_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+#define _nvkm_ibus_dtor _nvkm_subdev_dtor
+#define _nvkm_ibus_init _nvkm_subdev_init
+#define _nvkm_ibus_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass gf100_ibus_oclass;
+extern struct nvkm_oclass gk104_ibus_oclass;
+extern struct nvkm_oclass gk20a_ibus_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
new file mode 100644
index 000000000..1bcb763cf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -0,0 +1,49 @@
+#ifndef __NVKM_INSTMEM_H__
+#define __NVKM_INSTMEM_H__
+#include <core/subdev.h>
+
+struct nvkm_instobj {
+ struct nvkm_object base;
+ struct list_head head;
+ u32 *suspend;
+ u64 addr;
+ u32 size;
+};
+
+static inline struct nvkm_instobj *
+nv_memobj(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_MEMOBJ_CLASS)))
+ nv_assert("BAD CAST -> NvMemObj, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+struct nvkm_instmem {
+ struct nvkm_subdev base;
+ struct list_head list;
+
+ u32 reserved;
+ int (*alloc)(struct nvkm_instmem *, struct nvkm_object *,
+ u32 size, u32 align, struct nvkm_object **);
+};
+
+static inline struct nvkm_instmem *
+nvkm_instmem(void *obj)
+{
+ /* nv04/nv40 impls need to create objects in their constructor,
+ * which is before the subdev pointer is valid
+ */
+ if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
+ nv_subidx(obj) == NVDEV_SUBDEV_INSTMEM)
+ return obj;
+
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_INSTMEM);
+}
+
+extern struct nvkm_oclass *nv04_instmem_oclass;
+extern struct nvkm_oclass *nv40_instmem_oclass;
+extern struct nvkm_oclass *nv50_instmem_oclass;
+extern struct nvkm_oclass *gk20a_instmem_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
new file mode 100644
index 000000000..cd5d29fc0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
@@ -0,0 +1,31 @@
+#ifndef __NVKM_LTC_H__
+#define __NVKM_LTC_H__
+#include <core/subdev.h>
+struct nvkm_mm_node;
+
+#define NVKM_LTC_MAX_ZBC_CNT 16
+
+struct nvkm_ltc {
+ struct nvkm_subdev base;
+
+ int (*tags_alloc)(struct nvkm_ltc *, u32 count,
+ struct nvkm_mm_node **);
+ void (*tags_free)(struct nvkm_ltc *, struct nvkm_mm_node **);
+ void (*tags_clear)(struct nvkm_ltc *, u32 first, u32 count);
+
+ int zbc_min;
+ int zbc_max;
+ int (*zbc_color_get)(struct nvkm_ltc *, int index, const u32[4]);
+ int (*zbc_depth_get)(struct nvkm_ltc *, int index, const u32);
+};
+
+static inline struct nvkm_ltc *
+nvkm_ltc(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_LTC);
+}
+
+extern struct nvkm_oclass *gf100_ltc_oclass;
+extern struct nvkm_oclass *gk104_ltc_oclass;
+extern struct nvkm_oclass *gm107_ltc_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
new file mode 100644
index 000000000..055bea770
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_MC_H__
+#define __NVKM_MC_H__
+#include <core/subdev.h>
+
+struct nvkm_mc {
+ struct nvkm_subdev base;
+ bool use_msi;
+ unsigned int irq;
+ void (*unk260)(struct nvkm_mc *, u32);
+};
+
+static inline struct nvkm_mc *
+nvkm_mc(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_MC);
+}
+
+extern struct nvkm_oclass *nv04_mc_oclass;
+extern struct nvkm_oclass *nv40_mc_oclass;
+extern struct nvkm_oclass *nv44_mc_oclass;
+extern struct nvkm_oclass *nv4c_mc_oclass;
+extern struct nvkm_oclass *nv50_mc_oclass;
+extern struct nvkm_oclass *g94_mc_oclass;
+extern struct nvkm_oclass *g98_mc_oclass;
+extern struct nvkm_oclass *gf100_mc_oclass;
+extern struct nvkm_oclass *gf106_mc_oclass;
+extern struct nvkm_oclass *gk20a_mc_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
new file mode 100644
index 000000000..3a5368776
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
@@ -0,0 +1,104 @@
+#ifndef __NVKM_MMU_H__
+#define __NVKM_MMU_H__
+#include <core/subdev.h>
+#include <core/mm.h>
+struct nvkm_device;
+struct nvkm_mem;
+
+struct nvkm_vm_pgt {
+ struct nvkm_gpuobj *obj[2];
+ u32 refcount[2];
+};
+
+struct nvkm_vm_pgd {
+ struct list_head head;
+ struct nvkm_gpuobj *obj;
+};
+
+struct nvkm_vma {
+ struct list_head head;
+ int refcount;
+ struct nvkm_vm *vm;
+ struct nvkm_mm_node *node;
+ u64 offset;
+ u32 access;
+};
+
+struct nvkm_vm {
+ struct nvkm_mmu *mmu;
+ struct nvkm_mm mm;
+ struct kref refcount;
+
+ struct list_head pgd_list;
+ atomic_t engref[NVDEV_SUBDEV_NR];
+
+ struct nvkm_vm_pgt *pgt;
+ u32 fpde;
+ u32 lpde;
+};
+
+struct nvkm_mmu {
+ struct nvkm_subdev base;
+
+ u64 limit;
+ u8 dma_bits;
+ u32 pgt_bits;
+ u8 spg_shift;
+ u8 lpg_shift;
+
+ int (*create)(struct nvkm_mmu *, u64 offset, u64 length,
+ u64 mm_offset, struct nvkm_vm **);
+
+ void (*map_pgt)(struct nvkm_gpuobj *pgd, u32 pde,
+ struct nvkm_gpuobj *pgt[2]);
+ void (*map)(struct nvkm_vma *, struct nvkm_gpuobj *,
+ struct nvkm_mem *, u32 pte, u32 cnt,
+ u64 phys, u64 delta);
+ void (*map_sg)(struct nvkm_vma *, struct nvkm_gpuobj *,
+ struct nvkm_mem *, u32 pte, u32 cnt, dma_addr_t *);
+ void (*unmap)(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt);
+ void (*flush)(struct nvkm_vm *);
+};
+
+static inline struct nvkm_mmu *
+nvkm_mmu(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_MMU);
+}
+
+#define nvkm_mmu_create(p,e,o,i,f,d) \
+ nvkm_subdev_create((p), (e), (o), 0, (i), (f), (d))
+#define nvkm_mmu_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_mmu_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_mmu_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+#define _nvkm_mmu_dtor _nvkm_subdev_dtor
+#define _nvkm_mmu_init _nvkm_subdev_init
+#define _nvkm_mmu_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv04_mmu_oclass;
+extern struct nvkm_oclass nv41_mmu_oclass;
+extern struct nvkm_oclass nv44_mmu_oclass;
+extern struct nvkm_oclass nv50_mmu_oclass;
+extern struct nvkm_oclass gf100_mmu_oclass;
+
+int nv04_vm_create(struct nvkm_mmu *, u64, u64, u64,
+ struct nvkm_vm **);
+void nv04_mmu_dtor(struct nvkm_object *);
+
+int nvkm_vm_create(struct nvkm_mmu *, u64 offset, u64 length, u64 mm_offset,
+ u32 block, struct nvkm_vm **);
+int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset,
+ struct nvkm_vm **);
+int nvkm_vm_ref(struct nvkm_vm *, struct nvkm_vm **, struct nvkm_gpuobj *pgd);
+int nvkm_vm_get(struct nvkm_vm *, u64 size, u32 page_shift, u32 access,
+ struct nvkm_vma *);
+void nvkm_vm_put(struct nvkm_vma *);
+void nvkm_vm_map(struct nvkm_vma *, struct nvkm_mem *);
+void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *);
+void nvkm_vm_unmap(struct nvkm_vma *);
+void nvkm_vm_unmap_at(struct nvkm_vma *, u64 offset, u64 length);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h
new file mode 100644
index 000000000..fba613477
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_MXM_H__
+#define __NVKM_MXM_H__
+#include <core/subdev.h>
+
+#define MXM_SANITISE_DCB 0x00000001
+
+struct nvkm_mxm {
+ struct nvkm_subdev base;
+ u32 action;
+ u8 *mxms;
+};
+
+static inline struct nvkm_mxm *
+nvkm_mxm(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_MXM);
+}
+
+#define nvkm_mxm_create(p,e,o,d) \
+ nvkm_mxm_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_mxm_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_mxm_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+int nvkm_mxm_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void nvkm_mxm_destroy(struct nvkm_mxm *);
+
+#define _nvkm_mxm_dtor _nvkm_subdev_dtor
+#define _nvkm_mxm_init _nvkm_subdev_init
+#define _nvkm_mxm_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv50_mxm_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
new file mode 100644
index 000000000..755942352
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -0,0 +1,54 @@
+#ifndef __NVKM_PMU_H__
+#define __NVKM_PMU_H__
+#include <core/subdev.h>
+
+struct nvkm_pmu {
+ struct nvkm_subdev base;
+
+ struct {
+ u32 base;
+ u32 size;
+ } send;
+
+ struct {
+ u32 base;
+ u32 size;
+
+ struct work_struct work;
+ wait_queue_head_t wait;
+ u32 process;
+ u32 message;
+ u32 data[2];
+ } recv;
+
+ int (*message)(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
+ void (*pgob)(struct nvkm_pmu *, bool);
+};
+
+static inline struct nvkm_pmu *
+nvkm_pmu(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_PMU);
+}
+
+extern struct nvkm_oclass *gt215_pmu_oclass;
+extern struct nvkm_oclass *gf100_pmu_oclass;
+extern struct nvkm_oclass *gf110_pmu_oclass;
+extern struct nvkm_oclass *gk104_pmu_oclass;
+extern struct nvkm_oclass *gk110_pmu_oclass;
+extern struct nvkm_oclass *gk208_pmu_oclass;
+extern struct nvkm_oclass *gk20a_pmu_oclass;
+
+/* interface to MEMX process running on PMU */
+struct nvkm_memx;
+int nvkm_memx_init(struct nvkm_pmu *, struct nvkm_memx **);
+int nvkm_memx_fini(struct nvkm_memx **, bool exec);
+void nvkm_memx_wr32(struct nvkm_memx *, u32 addr, u32 data);
+void nvkm_memx_wait(struct nvkm_memx *, u32 addr, u32 mask, u32 data, u32 nsec);
+void nvkm_memx_nsec(struct nvkm_memx *, u32 nsec);
+void nvkm_memx_wait_vblank(struct nvkm_memx *);
+void nvkm_memx_train(struct nvkm_memx *);
+int nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
+void nvkm_memx_block(struct nvkm_memx *);
+void nvkm_memx_unblock(struct nvkm_memx *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
new file mode 100644
index 000000000..6662829b6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
@@ -0,0 +1,79 @@
+#ifndef __NVKM_THERM_H__
+#define __NVKM_THERM_H__
+#include <core/subdev.h>
+
+enum nvkm_therm_fan_mode {
+ NVKM_THERM_CTRL_NONE = 0,
+ NVKM_THERM_CTRL_MANUAL = 1,
+ NVKM_THERM_CTRL_AUTO = 2,
+};
+
+enum nvkm_therm_attr_type {
+ NVKM_THERM_ATTR_FAN_MIN_DUTY = 0,
+ NVKM_THERM_ATTR_FAN_MAX_DUTY = 1,
+ NVKM_THERM_ATTR_FAN_MODE = 2,
+
+ NVKM_THERM_ATTR_THRS_FAN_BOOST = 10,
+ NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST = 11,
+ NVKM_THERM_ATTR_THRS_DOWN_CLK = 12,
+ NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST = 13,
+ NVKM_THERM_ATTR_THRS_CRITICAL = 14,
+ NVKM_THERM_ATTR_THRS_CRITICAL_HYST = 15,
+ NVKM_THERM_ATTR_THRS_SHUTDOWN = 16,
+ NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
+};
+
+struct nvkm_therm {
+ struct nvkm_subdev base;
+
+ int (*pwm_ctrl)(struct nvkm_therm *, int line, bool);
+ int (*pwm_get)(struct nvkm_therm *, int line, u32 *, u32 *);
+ int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
+ int (*pwm_clock)(struct nvkm_therm *, int line);
+
+ int (*fan_get)(struct nvkm_therm *);
+ int (*fan_set)(struct nvkm_therm *, int);
+ int (*fan_sense)(struct nvkm_therm *);
+
+ int (*temp_get)(struct nvkm_therm *);
+
+ int (*attr_get)(struct nvkm_therm *, enum nvkm_therm_attr_type);
+ int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
+};
+
+static inline struct nvkm_therm *
+nvkm_therm(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_THERM);
+}
+
+#define nvkm_therm_create(p,e,o,d) \
+ nvkm_therm_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_therm_destroy(p) ({ \
+ struct nvkm_therm *therm = (p); \
+ _nvkm_therm_dtor(nv_object(therm)); \
+})
+#define nvkm_therm_init(p) ({ \
+ struct nvkm_therm *therm = (p); \
+ _nvkm_therm_init(nv_object(therm)); \
+})
+#define nvkm_therm_fini(p,s) ({ \
+ struct nvkm_therm *therm = (p); \
+ _nvkm_therm_init(nv_object(therm), (s)); \
+})
+
+int nvkm_therm_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_therm_dtor(struct nvkm_object *);
+int _nvkm_therm_init(struct nvkm_object *);
+int _nvkm_therm_fini(struct nvkm_object *, bool);
+
+int nvkm_therm_cstate(struct nvkm_therm *, int, int);
+
+extern struct nvkm_oclass nv40_therm_oclass;
+extern struct nvkm_oclass nv50_therm_oclass;
+extern struct nvkm_oclass g84_therm_oclass;
+extern struct nvkm_oclass gt215_therm_oclass;
+extern struct nvkm_oclass gf110_therm_oclass;
+extern struct nvkm_oclass gm107_therm_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
new file mode 100644
index 000000000..4ad55082e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
@@ -0,0 +1,61 @@
+#ifndef __NVKM_TIMER_H__
+#define __NVKM_TIMER_H__
+#include <core/subdev.h>
+
+struct nvkm_alarm {
+ struct list_head head;
+ u64 timestamp;
+ void (*func)(struct nvkm_alarm *);
+};
+
+static inline void
+nvkm_alarm_init(struct nvkm_alarm *alarm,
+ void (*func)(struct nvkm_alarm *))
+{
+ INIT_LIST_HEAD(&alarm->head);
+ alarm->func = func;
+}
+
+bool nvkm_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data);
+bool nvkm_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data);
+bool nvkm_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data);
+void nvkm_timer_alarm(void *, u32 nsec, struct nvkm_alarm *);
+void nvkm_timer_alarm_cancel(void *, struct nvkm_alarm *);
+
+#define NV_WAIT_DEFAULT 2000000000ULL
+#define nv_wait(o,a,m,v) \
+ nvkm_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v))
+#define nv_wait_ne(o,a,m,v) \
+ nvkm_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v))
+#define nv_wait_cb(o,c,d) \
+ nvkm_timer_wait_cb((o), NV_WAIT_DEFAULT, (c), (d))
+
+struct nvkm_timer {
+ struct nvkm_subdev base;
+ u64 (*read)(struct nvkm_timer *);
+ void (*alarm)(struct nvkm_timer *, u64 time, struct nvkm_alarm *);
+ void (*alarm_cancel)(struct nvkm_timer *, struct nvkm_alarm *);
+};
+
+static inline struct nvkm_timer *
+nvkm_timer(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_TIMER);
+}
+
+#define nvkm_timer_create(p,e,o,d) \
+ nvkm_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \
+ sizeof(**d), (void **)d)
+#define nvkm_timer_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_timer_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_timer_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+int nvkm_timer_create_(struct nvkm_object *, struct nvkm_engine *,
+ struct nvkm_oclass *, int size, void **);
+
+extern struct nvkm_oclass nv04_timer_oclass;
+extern struct nvkm_oclass gk20a_timer_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h
new file mode 100644
index 000000000..fee09ad81
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h
@@ -0,0 +1,30 @@
+#ifndef __NOUVEAU_VGA_H__
+#define __NOUVEAU_VGA_H__
+
+#include <core/os.h>
+
+/* access to various legacy io ports */
+u8 nv_rdport(void *obj, int head, u16 port);
+void nv_wrport(void *obj, int head, u16 port, u8 value);
+
+/* VGA Sequencer */
+u8 nv_rdvgas(void *obj, int head, u8 index);
+void nv_wrvgas(void *obj, int head, u8 index, u8 value);
+
+/* VGA Graphics */
+u8 nv_rdvgag(void *obj, int head, u8 index);
+void nv_wrvgag(void *obj, int head, u8 index, u8 value);
+
+/* VGA CRTC */
+u8 nv_rdvgac(void *obj, int head, u8 index);
+void nv_wrvgac(void *obj, int head, u8 index, u8 value);
+
+/* VGA indexed port access dispatcher */
+u8 nv_rdvgai(void *obj, int head, u16 port, u8 index);
+void nv_wrvgai(void *obj, int head, u16 port, u8 index, u8 value);
+
+bool nv_lockvgac(void *obj, bool lock);
+u8 nv_rdvgaowner(void *obj);
+void nv_wrvgaowner(void *obj, u8);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
new file mode 100644
index 000000000..e3d7243fb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
@@ -0,0 +1,58 @@
+#ifndef __NVKM_VOLT_H__
+#define __NVKM_VOLT_H__
+#include <core/subdev.h>
+
+struct nvkm_voltage {
+ u32 uv;
+ u8 id;
+};
+
+struct nvkm_volt {
+ struct nvkm_subdev base;
+
+ int (*vid_get)(struct nvkm_volt *);
+ int (*get)(struct nvkm_volt *);
+ int (*vid_set)(struct nvkm_volt *, u8 vid);
+ int (*set)(struct nvkm_volt *, u32 uv);
+ int (*set_id)(struct nvkm_volt *, u8 id, int condition);
+
+ u8 vid_mask;
+ u8 vid_nr;
+ struct {
+ u32 uv;
+ u8 vid;
+ } vid[256];
+};
+
+static inline struct nvkm_volt *
+nvkm_volt(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_VOLT);
+}
+
+#define nvkm_volt_create(p, e, o, d) \
+ nvkm_volt_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_volt_destroy(p) ({ \
+ struct nvkm_volt *v = (p); \
+ _nvkm_volt_dtor(nv_object(v)); \
+})
+#define nvkm_volt_init(p) ({ \
+ struct nvkm_volt *v = (p); \
+ _nvkm_volt_init(nv_object(v)); \
+})
+#define nvkm_volt_fini(p,s) \
+ nvkm_subdev_fini((p), (s))
+
+int nvkm_volt_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_volt_dtor(struct nvkm_object *);
+int _nvkm_volt_init(struct nvkm_object *);
+#define _nvkm_volt_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv40_volt_oclass;
+extern struct nvkm_oclass gk20a_volt_oclass;
+
+int nvkm_voltgpio_init(struct nvkm_volt *);
+int nvkm_voltgpio_get(struct nvkm_volt *);
+int nvkm_voltgpio_set(struct nvkm_volt *, u8);
+#endif