diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/include')
64 files changed, 3636 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h new file mode 100644 index 00000000..5a5961b6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -0,0 +1,361 @@ +#ifndef __NOUVEAU_CLASS_H__ +#define __NOUVEAU_CLASS_H__ + +/* Device class + * + * 0080: NV_DEVICE + */ +#define NV_DEVICE_CLASS 0x00000080 + +#define NV_DEVICE_DISABLE_IDENTIFY 0x0000000000000001ULL +#define NV_DEVICE_DISABLE_MMIO 0x0000000000000002ULL +#define NV_DEVICE_DISABLE_VBIOS 0x0000000000000004ULL +#define NV_DEVICE_DISABLE_CORE 0x0000000000000008ULL +#define NV_DEVICE_DISABLE_DISP 0x0000000000010000ULL +#define NV_DEVICE_DISABLE_FIFO 0x0000000000020000ULL +#define NV_DEVICE_DISABLE_GRAPH 0x0000000100000000ULL +#define NV_DEVICE_DISABLE_MPEG 0x0000000200000000ULL +#define NV_DEVICE_DISABLE_ME 0x0000000400000000ULL +#define NV_DEVICE_DISABLE_VP 0x0000000800000000ULL +#define NV_DEVICE_DISABLE_CRYPT 0x0000001000000000ULL +#define NV_DEVICE_DISABLE_BSP 0x0000002000000000ULL +#define NV_DEVICE_DISABLE_PPP 0x0000004000000000ULL +#define NV_DEVICE_DISABLE_COPY0 0x0000008000000000ULL +#define NV_DEVICE_DISABLE_COPY1 0x0000010000000000ULL +#define NV_DEVICE_DISABLE_UNK1C1 0x0000020000000000ULL +#define NV_DEVICE_DISABLE_VENC 0x0000040000000000ULL + +struct nv_device_class { + u64 device; /* device identifier, ~0 for client default */ + u64 disable; /* disable particular subsystems */ + u64 debug0; /* as above, but *internal* ids, and *NOT* ABI */ +}; + +/* DMA object classes + * + * 0002: NV_DMA_FROM_MEMORY + * 0003: NV_DMA_TO_MEMORY + * 003d: NV_DMA_IN_MEMORY + */ +#define NV_DMA_FROM_MEMORY_CLASS 0x00000002 +#define NV_DMA_TO_MEMORY_CLASS 0x00000003 +#define NV_DMA_IN_MEMORY_CLASS 0x0000003d + +#define NV_DMA_TARGET_MASK 0x000000ff +#define NV_DMA_TARGET_VM 0x00000000 +#define NV_DMA_TARGET_VRAM 0x00000001 +#define NV_DMA_TARGET_PCI 0x00000002 +#define NV_DMA_TARGET_PCI_US 0x00000003 +#define NV_DMA_TARGET_AGP 0x00000004 +#define NV_DMA_ACCESS_MASK 0x00000f00 +#define NV_DMA_ACCESS_VM 0x00000000 +#define NV_DMA_ACCESS_RD 0x00000100 +#define NV_DMA_ACCESS_WR 0x00000200 +#define NV_DMA_ACCESS_RDWR 0x00000300 + +/* NV50:NVC0 */ +#define NV50_DMA_CONF0_ENABLE 0x80000000 +#define NV50_DMA_CONF0_PRIV 0x00300000 +#define NV50_DMA_CONF0_PRIV_VM 0x00000000 +#define NV50_DMA_CONF0_PRIV_US 0x00100000 +#define NV50_DMA_CONF0_PRIV__S 0x00200000 +#define NV50_DMA_CONF0_PART 0x00030000 +#define NV50_DMA_CONF0_PART_VM 0x00000000 +#define NV50_DMA_CONF0_PART_256 0x00010000 +#define NV50_DMA_CONF0_PART_1KB 0x00020000 +#define NV50_DMA_CONF0_COMP 0x00000180 +#define NV50_DMA_CONF0_COMP_NONE 0x00000000 +#define NV50_DMA_CONF0_COMP_VM 0x00000180 +#define NV50_DMA_CONF0_TYPE 0x0000007f +#define NV50_DMA_CONF0_TYPE_LINEAR 0x00000000 +#define NV50_DMA_CONF0_TYPE_VM 0x0000007f + +/* NVC0:NVD9 */ +#define NVC0_DMA_CONF0_ENABLE 0x80000000 +#define NVC0_DMA_CONF0_PRIV 0x00300000 +#define NVC0_DMA_CONF0_PRIV_VM 0x00000000 +#define NVC0_DMA_CONF0_PRIV_US 0x00100000 +#define NVC0_DMA_CONF0_PRIV__S 0x00200000 +#define NVC0_DMA_CONF0_UNKN /* PART? */ 0x00030000 +#define NVC0_DMA_CONF0_TYPE 0x000000ff +#define NVC0_DMA_CONF0_TYPE_LINEAR 0x00000000 +#define NVC0_DMA_CONF0_TYPE_VM 0x000000ff + +/* NVD9- */ +#define NVD0_DMA_CONF0_ENABLE 0x80000000 +#define NVD0_DMA_CONF0_PAGE 0x00000400 +#define NVD0_DMA_CONF0_PAGE_LP 0x00000000 +#define NVD0_DMA_CONF0_PAGE_SP 0x00000400 +#define NVD0_DMA_CONF0_TYPE 0x000000ff +#define NVD0_DMA_CONF0_TYPE_LINEAR 0x00000000 +#define NVD0_DMA_CONF0_TYPE_VM 0x000000ff + +struct nv_dma_class { + u32 flags; + u32 pad0; + u64 start; + u64 limit; + u32 conf0; +}; + +/* DMA FIFO channel classes + * + * 006b: NV03_CHANNEL_DMA + * 006e: NV10_CHANNEL_DMA + * 176e: NV17_CHANNEL_DMA + * 406e: NV40_CHANNEL_DMA + * 506e: NV50_CHANNEL_DMA + * 826e: NV84_CHANNEL_DMA + */ +#define NV03_CHANNEL_DMA_CLASS 0x0000006b +#define NV10_CHANNEL_DMA_CLASS 0x0000006e +#define NV17_CHANNEL_DMA_CLASS 0x0000176e +#define NV40_CHANNEL_DMA_CLASS 0x0000406e +#define NV50_CHANNEL_DMA_CLASS 0x0000506e +#define NV84_CHANNEL_DMA_CLASS 0x0000826e + +struct nv03_channel_dma_class { + u32 pushbuf; + u32 pad0; + u64 offset; +}; + +/* Indirect FIFO channel classes + * + * 506f: NV50_CHANNEL_IND + * 826f: NV84_CHANNEL_IND + * 906f: NVC0_CHANNEL_IND + * a06f: NVE0_CHANNEL_IND + */ + +#define NV50_CHANNEL_IND_CLASS 0x0000506f +#define NV84_CHANNEL_IND_CLASS 0x0000826f +#define NVC0_CHANNEL_IND_CLASS 0x0000906f +#define NVE0_CHANNEL_IND_CLASS 0x0000a06f + +struct nv50_channel_ind_class { + u32 pushbuf; + u32 ilength; + u64 ioffset; +}; + +#define NVE0_CHANNEL_IND_ENGINE_GR 0x00000001 +#define NVE0_CHANNEL_IND_ENGINE_VP 0x00000002 +#define NVE0_CHANNEL_IND_ENGINE_PPP 0x00000004 +#define NVE0_CHANNEL_IND_ENGINE_BSP 0x00000008 +#define NVE0_CHANNEL_IND_ENGINE_CE0 0x00000010 +#define NVE0_CHANNEL_IND_ENGINE_CE1 0x00000020 +#define NVE0_CHANNEL_IND_ENGINE_ENC 0x00000040 + +struct nve0_channel_ind_class { + u32 pushbuf; + u32 ilength; + u64 ioffset; + u32 engine; +}; + +/* 0046: NV04_DISP + */ + +#define NV04_DISP_CLASS 0x00000046 + +struct nv04_display_class { +}; + +/* 5070: NV50_DISP + * 8270: NV84_DISP + * 8370: NVA0_DISP + * 8870: NV94_DISP + * 8570: NVA3_DISP + * 9070: NVD0_DISP + * 9170: NVE0_DISP + * 9270: NVF0_DISP + */ + +#define NV50_DISP_CLASS 0x00005070 +#define NV84_DISP_CLASS 0x00008270 +#define NVA0_DISP_CLASS 0x00008370 +#define NV94_DISP_CLASS 0x00008870 +#define NVA3_DISP_CLASS 0x00008570 +#define NVD0_DISP_CLASS 0x00009070 +#define NVE0_DISP_CLASS 0x00009170 +#define NVF0_DISP_CLASS 0x00009270 + +#define NV50_DISP_SOR_MTHD 0x00010000 +#define NV50_DISP_SOR_MTHD_TYPE 0x0000f000 +#define NV50_DISP_SOR_MTHD_HEAD 0x00000018 +#define NV50_DISP_SOR_MTHD_LINK 0x00000004 +#define NV50_DISP_SOR_MTHD_OR 0x00000003 + +#define NV50_DISP_SOR_PWR 0x00010000 +#define NV50_DISP_SOR_PWR_STATE 0x00000001 +#define NV50_DISP_SOR_PWR_STATE_ON 0x00000001 +#define NV50_DISP_SOR_PWR_STATE_OFF 0x00000000 +#define NVA3_DISP_SOR_HDA_ELD 0x00010100 +#define NV84_DISP_SOR_HDMI_PWR 0x00012000 +#define NV84_DISP_SOR_HDMI_PWR_STATE 0x40000000 +#define NV84_DISP_SOR_HDMI_PWR_STATE_OFF 0x00000000 +#define NV84_DISP_SOR_HDMI_PWR_STATE_ON 0x40000000 +#define NV84_DISP_SOR_HDMI_PWR_MAX_AC_PACKET 0x001f0000 +#define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f +#define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000 +#define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff + +#define NV50_DISP_DAC_MTHD 0x00020000 +#define NV50_DISP_DAC_MTHD_TYPE 0x0000f000 +#define NV50_DISP_DAC_MTHD_OR 0x00000003 + +#define NV50_DISP_DAC_PWR 0x00020000 +#define NV50_DISP_DAC_PWR_HSYNC 0x00000001 +#define NV50_DISP_DAC_PWR_HSYNC_ON 0x00000000 +#define NV50_DISP_DAC_PWR_HSYNC_LO 0x00000001 +#define NV50_DISP_DAC_PWR_VSYNC 0x00000004 +#define NV50_DISP_DAC_PWR_VSYNC_ON 0x00000000 +#define NV50_DISP_DAC_PWR_VSYNC_LO 0x00000004 +#define NV50_DISP_DAC_PWR_DATA 0x00000010 +#define NV50_DISP_DAC_PWR_DATA_ON 0x00000000 +#define NV50_DISP_DAC_PWR_DATA_LO 0x00000010 +#define NV50_DISP_DAC_PWR_STATE 0x00000040 +#define NV50_DISP_DAC_PWR_STATE_ON 0x00000000 +#define NV50_DISP_DAC_PWR_STATE_OFF 0x00000040 +#define NV50_DISP_DAC_LOAD 0x00020100 +#define NV50_DISP_DAC_LOAD_VALUE 0x00000007 + +#define NV50_DISP_PIOR_MTHD 0x00030000 +#define NV50_DISP_PIOR_MTHD_TYPE 0x0000f000 +#define NV50_DISP_PIOR_MTHD_OR 0x00000003 + +#define NV50_DISP_PIOR_PWR 0x00030000 +#define NV50_DISP_PIOR_PWR_STATE 0x00000001 +#define NV50_DISP_PIOR_PWR_STATE_ON 0x00000001 +#define NV50_DISP_PIOR_PWR_STATE_OFF 0x00000000 +#define NV50_DISP_PIOR_TMDS_PWR 0x00032000 +#define NV50_DISP_PIOR_TMDS_PWR_STATE 0x00000001 +#define NV50_DISP_PIOR_TMDS_PWR_STATE_ON 0x00000001 +#define NV50_DISP_PIOR_TMDS_PWR_STATE_OFF 0x00000000 +#define NV50_DISP_PIOR_DP_PWR 0x00036000 +#define NV50_DISP_PIOR_DP_PWR_STATE 0x00000001 +#define NV50_DISP_PIOR_DP_PWR_STATE_ON 0x00000001 +#define NV50_DISP_PIOR_DP_PWR_STATE_OFF 0x00000000 + +struct nv50_display_class { +}; + +/* 507a: NV50_DISP_CURS + * 827a: NV84_DISP_CURS + * 837a: NVA0_DISP_CURS + * 887a: NV94_DISP_CURS + * 857a: NVA3_DISP_CURS + * 907a: NVD0_DISP_CURS + * 917a: NVE0_DISP_CURS + * 927a: NVF0_DISP_CURS + */ + +#define NV50_DISP_CURS_CLASS 0x0000507a +#define NV84_DISP_CURS_CLASS 0x0000827a +#define NVA0_DISP_CURS_CLASS 0x0000837a +#define NV94_DISP_CURS_CLASS 0x0000887a +#define NVA3_DISP_CURS_CLASS 0x0000857a +#define NVD0_DISP_CURS_CLASS 0x0000907a +#define NVE0_DISP_CURS_CLASS 0x0000917a +#define NVF0_DISP_CURS_CLASS 0x0000927a + +struct nv50_display_curs_class { + u32 head; +}; + +/* 507b: NV50_DISP_OIMM + * 827b: NV84_DISP_OIMM + * 837b: NVA0_DISP_OIMM + * 887b: NV94_DISP_OIMM + * 857b: NVA3_DISP_OIMM + * 907b: NVD0_DISP_OIMM + * 917b: NVE0_DISP_OIMM + * 927b: NVE0_DISP_OIMM + */ + +#define NV50_DISP_OIMM_CLASS 0x0000507b +#define NV84_DISP_OIMM_CLASS 0x0000827b +#define NVA0_DISP_OIMM_CLASS 0x0000837b +#define NV94_DISP_OIMM_CLASS 0x0000887b +#define NVA3_DISP_OIMM_CLASS 0x0000857b +#define NVD0_DISP_OIMM_CLASS 0x0000907b +#define NVE0_DISP_OIMM_CLASS 0x0000917b +#define NVF0_DISP_OIMM_CLASS 0x0000927b + +struct nv50_display_oimm_class { + u32 head; +}; + +/* 507c: NV50_DISP_SYNC + * 827c: NV84_DISP_SYNC + * 837c: NVA0_DISP_SYNC + * 887c: NV94_DISP_SYNC + * 857c: NVA3_DISP_SYNC + * 907c: NVD0_DISP_SYNC + * 917c: NVE0_DISP_SYNC + * 927c: NVF0_DISP_SYNC + */ + +#define NV50_DISP_SYNC_CLASS 0x0000507c +#define NV84_DISP_SYNC_CLASS 0x0000827c +#define NVA0_DISP_SYNC_CLASS 0x0000837c +#define NV94_DISP_SYNC_CLASS 0x0000887c +#define NVA3_DISP_SYNC_CLASS 0x0000857c +#define NVD0_DISP_SYNC_CLASS 0x0000907c +#define NVE0_DISP_SYNC_CLASS 0x0000917c +#define NVF0_DISP_SYNC_CLASS 0x0000927c + +struct nv50_display_sync_class { + u32 pushbuf; + u32 head; +}; + +/* 507d: NV50_DISP_MAST + * 827d: NV84_DISP_MAST + * 837d: NVA0_DISP_MAST + * 887d: NV94_DISP_MAST + * 857d: NVA3_DISP_MAST + * 907d: NVD0_DISP_MAST + * 917d: NVE0_DISP_MAST + * 927d: NVF0_DISP_MAST + */ + +#define NV50_DISP_MAST_CLASS 0x0000507d +#define NV84_DISP_MAST_CLASS 0x0000827d +#define NVA0_DISP_MAST_CLASS 0x0000837d +#define NV94_DISP_MAST_CLASS 0x0000887d +#define NVA3_DISP_MAST_CLASS 0x0000857d +#define NVD0_DISP_MAST_CLASS 0x0000907d +#define NVE0_DISP_MAST_CLASS 0x0000917d +#define NVF0_DISP_MAST_CLASS 0x0000927d + +struct nv50_display_mast_class { + u32 pushbuf; +}; + +/* 507e: NV50_DISP_OVLY + * 827e: NV84_DISP_OVLY + * 837e: NVA0_DISP_OVLY + * 887e: NV94_DISP_OVLY + * 857e: NVA3_DISP_OVLY + * 907e: NVD0_DISP_OVLY + * 917e: NVE0_DISP_OVLY + * 927e: NVF0_DISP_OVLY + */ + +#define NV50_DISP_OVLY_CLASS 0x0000507e +#define NV84_DISP_OVLY_CLASS 0x0000827e +#define NVA0_DISP_OVLY_CLASS 0x0000837e +#define NV94_DISP_OVLY_CLASS 0x0000887e +#define NVA3_DISP_OVLY_CLASS 0x0000857e +#define NVD0_DISP_OVLY_CLASS 0x0000907e +#define NVE0_DISP_OVLY_CLASS 0x0000917e +#define NVF0_DISP_OVLY_CLASS 0x0000927e + +struct nv50_display_ovly_class { + u32 pushbuf; + u32 head; +}; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h new file mode 100644 index 00000000..c66eac51 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/client.h @@ -0,0 +1,46 @@ +#ifndef __NOUVEAU_CLIENT_H__ +#define __NOUVEAU_CLIENT_H__ + +#include <core/namedb.h> + +struct nouveau_client { + struct nouveau_namedb base; + struct nouveau_handle *root; + struct nouveau_object *device; + char name[32]; + u32 debug; + struct nouveau_vm *vm; +}; + +static inline struct nouveau_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 nouveau_client * +nouveau_client(void *obj) +{ + struct nouveau_object *client = nv_object(obj); + while (client && !(nv_iclass(client, NV_CLIENT_CLASS))) + client = client->parent; + return (void *)client; +} + +#define nouveau_client_create(n,c,oc,od,d) \ + nouveau_client_create_((n), (c), (oc), (od), sizeof(**d), (void **)d) + +int nouveau_client_create_(const char *name, u64 device, const char *cfg, + const char *dbg, int, void **); +#define nouveau_client_destroy(p) \ + nouveau_namedb_destroy(&(p)->base) + +int nouveau_client_init(struct nouveau_client *); +int nouveau_client_fini(struct nouveau_client *, bool suspend); +const char *nouveau_client_name(void *obj); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/debug.h b/drivers/gpu/drm/nouveau/core/include/core/debug.h new file mode 100644 index 00000000..9ea18dfc --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/debug.h @@ -0,0 +1,13 @@ +#ifndef __NOUVEAU_DEBUG_H__ +#define __NOUVEAU_DEBUG_H__ + +#define NV_DBG_FATAL 0 +#define NV_DBG_ERROR 1 +#define NV_DBG_WARN 2 +#define NV_DBG_INFO 3 +#define NV_DBG_DEBUG 4 +#define NV_DBG_TRACE 5 +#define NV_DBG_PARANOIA 6 +#define NV_DBG_SPAM 7 + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h new file mode 100644 index 00000000..05840f3e --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/device.h @@ -0,0 +1,137 @@ +#ifndef __NOUVEAU_DEVICE_H__ +#define __NOUVEAU_DEVICE_H__ + +#include <core/object.h> +#include <core/subdev.h> +#include <core/engine.h> + +enum nv_subdev_type { + NVDEV_ENGINE_DEVICE, + NVDEV_SUBDEV_VBIOS, + + /* All subdevs from DEVINIT to DEVINIT_LAST will be created before + * *any* of them are initialised. This subdev category is used + * for any subdevs that the VBIOS init table parsing may call out + * to during POST. + */ + NVDEV_SUBDEV_DEVINIT, + NVDEV_SUBDEV_GPIO, + NVDEV_SUBDEV_I2C, + NVDEV_SUBDEV_CLOCK, + NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_CLOCK, + + /* This grouping of subdevs are initialised right after they've + * been created, and are allowed to assume any subdevs in the + * list above them exist and have been initialised. + */ + NVDEV_SUBDEV_MXM, + NVDEV_SUBDEV_MC, + NVDEV_SUBDEV_BUS, + NVDEV_SUBDEV_TIMER, + NVDEV_SUBDEV_FB, + NVDEV_SUBDEV_LTCG, + NVDEV_SUBDEV_IBUS, + NVDEV_SUBDEV_INSTMEM, + NVDEV_SUBDEV_VM, + NVDEV_SUBDEV_BAR, + NVDEV_SUBDEV_VOLT, + NVDEV_SUBDEV_THERM, + + NVDEV_ENGINE_DMAOBJ, + NVDEV_ENGINE_FIFO, + NVDEV_ENGINE_SW, + NVDEV_ENGINE_GR, + NVDEV_ENGINE_MPEG, + NVDEV_ENGINE_ME, + NVDEV_ENGINE_VP, + NVDEV_ENGINE_CRYPT, + NVDEV_ENGINE_BSP, + NVDEV_ENGINE_PPP, + NVDEV_ENGINE_COPY0, + NVDEV_ENGINE_COPY1, + NVDEV_ENGINE_UNK1C1, + NVDEV_ENGINE_VENC, + NVDEV_ENGINE_DISP, + + NVDEV_SUBDEV_NR, +}; + +struct nouveau_device { + struct nouveau_engine base; + struct list_head head; + + struct pci_dev *pdev; + u64 handle; + + const char *cfgopt; + const char *dbgopt; + const char *name; + const char *cname; + + enum { + NV_04 = 0x04, + NV_10 = 0x10, + NV_20 = 0x20, + NV_30 = 0x30, + NV_40 = 0x40, + NV_50 = 0x50, + NV_C0 = 0xc0, + NV_D0 = 0xd0, + NV_E0 = 0xe0, + } card_type; + u32 chipset; + u32 crystal; + + struct nouveau_oclass *oclass[NVDEV_SUBDEV_NR]; + struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; +}; + +static inline struct nouveau_device * +nv_device(void *obj) +{ + struct nouveau_object *object = nv_object(obj); + struct nouveau_object *device = object; + + if (device->engine) + device = device->engine; + if (device->parent) + device = device->parent; + +#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA + if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) || + (nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) { + nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x", + nv_hclass(object), nv_hclass(device)); + } +#endif + + return (void *)device; +} + +static inline struct nouveau_subdev * +nouveau_subdev(void *obj, int sub) +{ + if (nv_device(obj)->subdev[sub]) + return nv_subdev(nv_device(obj)->subdev[sub]); + return NULL; +} + +static inline struct nouveau_engine * +nouveau_engine(void *obj, int sub) +{ + struct nouveau_subdev *subdev = nouveau_subdev(obj, sub); + if (subdev && nv_iclass(subdev, NV_ENGINE_CLASS)) + return nv_engine(subdev); + return NULL; +} + +static inline bool +nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub) +{ + struct nouveau_device *device = nv_device(object); + return device->pdev->device == dev && + device->pdev->subsystem_vendor == ven && + device->pdev->subsystem_device == sub; +} + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/engctx.h b/drivers/gpu/drm/nouveau/core/include/core/engctx.h new file mode 100644 index 00000000..2fd48b56 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/engctx.h @@ -0,0 +1,54 @@ +#ifndef __NOUVEAU_ENGCTX_H__ +#define __NOUVEAU_ENGCTX_H__ + +#include <core/object.h> +#include <core/gpuobj.h> + +#include <subdev/vm.h> + +#define NV_ENGCTX_(eng,var) (NV_ENGCTX_CLASS | ((var) << 8) | (eng)) +#define NV_ENGCTX(name,var) NV_ENGCTX_(NVDEV_ENGINE_##name, (var)) + +struct nouveau_engctx { + struct nouveau_gpuobj base; + struct nouveau_vma vma; + struct list_head head; + unsigned long save; + u64 addr; +}; + +static inline struct nouveau_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 nouveau_engctx_create(p,e,c,g,s,a,f,d) \ + nouveau_engctx_create_((p), (e), (c), (g), (s), (a), (f), \ + sizeof(**d), (void **)d) + +int nouveau_engctx_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, struct nouveau_object *, + u32 size, u32 align, u32 flags, + int length, void **data); +void nouveau_engctx_destroy(struct nouveau_engctx *); +int nouveau_engctx_init(struct nouveau_engctx *); +int nouveau_engctx_fini(struct nouveau_engctx *, bool suspend); + +int _nouveau_engctx_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void _nouveau_engctx_dtor(struct nouveau_object *); +int _nouveau_engctx_init(struct nouveau_object *); +int _nouveau_engctx_fini(struct nouveau_object *, bool suspend); +#define _nouveau_engctx_rd32 _nouveau_gpuobj_rd32 +#define _nouveau_engctx_wr32 _nouveau_gpuobj_wr32 + +struct nouveau_object *nouveau_engctx_get(struct nouveau_engine *, u64 addr); +void nouveau_engctx_put(struct nouveau_object *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/engine.h b/drivers/gpu/drm/nouveau/core/include/core/engine.h new file mode 100644 index 00000000..666d06de --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/engine.h @@ -0,0 +1,57 @@ +#ifndef __NOUVEAU_ENGINE_H__ +#define __NOUVEAU_ENGINE_H__ + +#include <core/object.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 nouveau_engine { + struct nouveau_subdev base; + struct nouveau_oclass *cclass; + struct nouveau_oclass *sclass; + + struct list_head contexts; + spinlock_t lock; + + void (*tile_prog)(struct nouveau_engine *, int region); + int (*tlb_flush)(struct nouveau_engine *); +}; + +static inline struct nouveau_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 nouveau_object *object) +{ + return nv_subidx(object); +} + +#define nouveau_engine_create(p,e,c,d,i,f,r) \ + nouveau_engine_create_((p), (e), (c), (d), (i), (f), \ + sizeof(**r),(void **)r) + +#define nouveau_engine_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_engine_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_engine_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +int nouveau_engine_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, bool, const char *, + const char *, int, void **); + +#define _nouveau_engine_dtor _nouveau_subdev_dtor +#define _nouveau_engine_init _nouveau_subdev_init +#define _nouveau_engine_fini _nouveau_subdev_fini + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/enum.h b/drivers/gpu/drm/nouveau/core/include/core/enum.h new file mode 100644 index 00000000..4fc62bb8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/enum.h @@ -0,0 +1,24 @@ +#ifndef __NOUVEAU_ENUM_H__ +#define __NOUVEAU_ENUM_H__ + +struct nouveau_enum { + u32 value; + const char *name; + const void *data; + u32 data2; +}; + +const struct nouveau_enum * +nouveau_enum_find(const struct nouveau_enum *, u32 value); + +const struct nouveau_enum * +nouveau_enum_print(const struct nouveau_enum *en, u32 value); + +struct nouveau_bitfield { + u32 mask; + const char *name; +}; + +void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/event.h b/drivers/gpu/drm/nouveau/core/include/core/event.h new file mode 100644 index 00000000..9e094408 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/event.h @@ -0,0 +1,36 @@ +#ifndef __NVKM_EVENT_H__ +#define __NVKM_EVENT_H__ + +/* return codes from event handlers */ +#define NVKM_EVENT_DROP 0 +#define NVKM_EVENT_KEEP 1 + +struct nouveau_eventh { + struct list_head head; + int (*func)(struct nouveau_eventh *, int index); +}; + +struct nouveau_event { + spinlock_t lock; + + void *priv; + void (*enable)(struct nouveau_event *, int index); + void (*disable)(struct nouveau_event *, int index); + + int index_nr; + struct { + struct list_head list; + int refs; + } index[]; +}; + +int nouveau_event_create(int index_nr, struct nouveau_event **); +void nouveau_event_destroy(struct nouveau_event **); +void nouveau_event_trigger(struct nouveau_event *, int index); + +void nouveau_event_get(struct nouveau_event *, int index, + struct nouveau_eventh *); +void nouveau_event_put(struct nouveau_event *, int index, + struct nouveau_eventh *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/falcon.h b/drivers/gpu/drm/nouveau/core/include/core/falcon.h new file mode 100644 index 00000000..1edec386 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/falcon.h @@ -0,0 +1,81 @@ +#ifndef __NOUVEAU_FALCON_H__ +#define __NOUVEAU_FALCON_H__ + +#include <core/engine.h> +#include <core/engctx.h> +#include <core/gpuobj.h> + +struct nouveau_falcon_chan { + struct nouveau_engctx base; +}; + +#define nouveau_falcon_context_create(p,e,c,g,s,a,f,d) \ + nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d)) +#define nouveau_falcon_context_destroy(d) \ + nouveau_engctx_destroy(&(d)->base) +#define nouveau_falcon_context_init(d) \ + nouveau_engctx_init(&(d)->base) +#define nouveau_falcon_context_fini(d,s) \ + nouveau_engctx_fini(&(d)->base, (s)) + +#define _nouveau_falcon_context_ctor _nouveau_engctx_ctor +#define _nouveau_falcon_context_dtor _nouveau_engctx_dtor +#define _nouveau_falcon_context_init _nouveau_engctx_init +#define _nouveau_falcon_context_fini _nouveau_engctx_fini +#define _nouveau_falcon_context_rd32 _nouveau_engctx_rd32 +#define _nouveau_falcon_context_wr32 _nouveau_engctx_wr32 + +struct nouveau_falcon_data { + bool external; +}; + +struct nouveau_falcon { + struct nouveau_engine base; + + u32 addr; + u8 version; + u8 secret; + + struct nouveau_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 nouveau_falcon_create(p,e,c,b,d,i,f,r) \ + nouveau_falcon_create_((p), (e), (c), (b), (d), (i), (f), \ + sizeof(**r),(void **)r) +#define nouveau_falcon_destroy(p) \ + nouveau_engine_destroy(&(p)->base) +#define nouveau_falcon_init(p) ({ \ + struct nouveau_falcon *falcon = (p); \ + _nouveau_falcon_init(nv_object(falcon)); \ +}) +#define nouveau_falcon_fini(p,s) ({ \ + struct nouveau_falcon *falcon = (p); \ + _nouveau_falcon_fini(nv_object(falcon), (s)); \ +}) + +int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u32, bool, const char *, + const char *, int, void **); + +#define _nouveau_falcon_dtor _nouveau_engine_dtor +int _nouveau_falcon_init(struct nouveau_object *); +int _nouveau_falcon_fini(struct nouveau_object *, bool); +u32 _nouveau_falcon_rd32(struct nouveau_object *, u64); +void _nouveau_falcon_wr32(struct nouveau_object *, u64, u32); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h new file mode 100644 index 00000000..b3b9ce4e --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h @@ -0,0 +1,71 @@ +#ifndef __NOUVEAU_GPUOBJ_H__ +#define __NOUVEAU_GPUOBJ_H__ + +#include <core/object.h> +#include <core/device.h> +#include <core/parent.h> +#include <core/mm.h> + +struct nouveau_vma; +struct nouveau_vm; + +#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001 +#define NVOBJ_FLAG_ZERO_FREE 0x00000002 +#define NVOBJ_FLAG_HEAP 0x00000004 + +struct nouveau_gpuobj { + struct nouveau_object base; + struct nouveau_object *parent; + struct nouveau_mm_node *node; + struct nouveau_mm heap; + + u32 flags; + u64 addr; + u32 size; +}; + +static inline struct nouveau_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 nouveau_gpuobj_create(p,e,c,v,g,s,a,f,d) \ + nouveau_gpuobj_create_((p), (e), (c), (v), (g), (s), (a), (f), \ + sizeof(**d), (void **)d) +#define nouveau_gpuobj_init(p) nouveau_object_init(&(p)->base) +#define nouveau_gpuobj_fini(p,s) nouveau_object_fini(&(p)->base, (s)) +int nouveau_gpuobj_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u32 pclass, + struct nouveau_object *, u32 size, u32 align, + u32 flags, int length, void **); +void nouveau_gpuobj_destroy(struct nouveau_gpuobj *); + +int nouveau_gpuobj_new(struct nouveau_object *, struct nouveau_object *, + u32 size, u32 align, u32 flags, + struct nouveau_gpuobj **); +int nouveau_gpuobj_dup(struct nouveau_object *, struct nouveau_gpuobj *, + struct nouveau_gpuobj **); + +int nouveau_gpuobj_map(struct nouveau_gpuobj *, u32 acc, struct nouveau_vma *); +int nouveau_gpuobj_map_vm(struct nouveau_gpuobj *, struct nouveau_vm *, + u32 access, struct nouveau_vma *); +void nouveau_gpuobj_unmap(struct nouveau_vma *); + +static inline void +nouveau_gpuobj_ref(struct nouveau_gpuobj *obj, struct nouveau_gpuobj **ref) +{ + nouveau_object_ref(&obj->base, (struct nouveau_object **)ref); +} + +void _nouveau_gpuobj_dtor(struct nouveau_object *); +int _nouveau_gpuobj_init(struct nouveau_object *); +int _nouveau_gpuobj_fini(struct nouveau_object *, bool); +u32 _nouveau_gpuobj_rd32(struct nouveau_object *, u64); +void _nouveau_gpuobj_wr32(struct nouveau_object *, u64, u32); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/handle.h b/drivers/gpu/drm/nouveau/core/include/core/handle.h new file mode 100644 index 00000000..363674cd --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/handle.h @@ -0,0 +1,31 @@ +#ifndef __NOUVEAU_HANDLE_H__ +#define __NOUVEAU_HANDLE_H__ + +struct nouveau_handle { + struct nouveau_namedb *namedb; + struct list_head node; + + struct list_head head; + struct list_head tree; + u32 name; + u32 priv; + + struct nouveau_handle *parent; + struct nouveau_object *object; +}; + +int nouveau_handle_create(struct nouveau_object *, u32 parent, u32 handle, + struct nouveau_object *, struct nouveau_handle **); +void nouveau_handle_destroy(struct nouveau_handle *); +int nouveau_handle_init(struct nouveau_handle *); +int nouveau_handle_fini(struct nouveau_handle *, bool suspend); + +struct nouveau_object * +nouveau_handle_ref(struct nouveau_object *, u32 name); + +struct nouveau_handle *nouveau_handle_get_class(struct nouveau_object *, u16); +struct nouveau_handle *nouveau_handle_get_vinst(struct nouveau_object *, u64); +struct nouveau_handle *nouveau_handle_get_cinst(struct nouveau_object *, u32); +void nouveau_handle_put(struct nouveau_handle *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/math.h b/drivers/gpu/drm/nouveau/core/include/core/math.h new file mode 100644 index 00000000..f808131c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/math.h @@ -0,0 +1,16 @@ +#ifndef __NOUVEAU_MATH_H__ +#define __NOUVEAU_MATH_H__ + +static inline int +log2i(u64 base) +{ + u64 temp = base >> 1; + int log2; + + for (log2 = 0; temp; log2++, temp >>= 1) { + } + + return (base & (base - 1)) ? log2 + 1: log2; +} + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h new file mode 100644 index 00000000..2514e81a --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/mm.h @@ -0,0 +1,38 @@ +#ifndef __NOUVEAU_MM_H__ +#define __NOUVEAU_MM_H__ + +struct nouveau_mm_node { + struct list_head nl_entry; + struct list_head fl_entry; + struct list_head rl_entry; + + u8 type; + u32 offset; + u32 length; +}; + +struct nouveau_mm { + struct list_head nodes; + struct list_head free; + + struct mutex mutex; + + u32 block_size; + int heap_nodes; +}; + +static inline bool +nouveau_mm_initialised(struct nouveau_mm *mm) +{ + return mm->block_size != 0; +} + +int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); +int nouveau_mm_fini(struct nouveau_mm *); +int nouveau_mm_head(struct nouveau_mm *, u8 type, u32 size_max, u32 size_min, + u32 align, struct nouveau_mm_node **); +int nouveau_mm_tail(struct nouveau_mm *, u8 type, u32 size_max, u32 size_min, + u32 align, struct nouveau_mm_node **); +void nouveau_mm_free(struct nouveau_mm *, struct nouveau_mm_node **); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/namedb.h b/drivers/gpu/drm/nouveau/core/include/core/namedb.h new file mode 100644 index 00000000..8897e088 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/namedb.h @@ -0,0 +1,56 @@ +#ifndef __NOUVEAU_NAMEDB_H__ +#define __NOUVEAU_NAMEDB_H__ + +#include <core/parent.h> + +struct nouveau_handle; + +struct nouveau_namedb { + struct nouveau_parent base; + rwlock_t lock; + struct list_head list; +}; + +static inline struct nouveau_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 nouveau_namedb_create(p,e,c,v,s,m,d) \ + nouveau_namedb_create_((p), (e), (c), (v), (s), (m), \ + sizeof(**d), (void **)d) +#define nouveau_namedb_init(p) \ + nouveau_parent_init(&(p)->base) +#define nouveau_namedb_fini(p,s) \ + nouveau_parent_fini(&(p)->base, (s)) +#define nouveau_namedb_destroy(p) \ + nouveau_parent_destroy(&(p)->base) + +int nouveau_namedb_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u32 pclass, + struct nouveau_oclass *, u32 engcls, + int size, void **); + +int _nouveau_namedb_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +#define _nouveau_namedb_dtor _nouveau_parent_dtor +#define _nouveau_namedb_init _nouveau_parent_init +#define _nouveau_namedb_fini _nouveau_parent_fini + +int nouveau_namedb_insert(struct nouveau_namedb *, u32 name, + struct nouveau_object *, struct nouveau_handle *); +void nouveau_namedb_remove(struct nouveau_handle *); + +struct nouveau_handle *nouveau_namedb_get(struct nouveau_namedb *, u32); +struct nouveau_handle *nouveau_namedb_get_class(struct nouveau_namedb *, u16); +struct nouveau_handle *nouveau_namedb_get_vinst(struct nouveau_namedb *, u64); +struct nouveau_handle *nouveau_namedb_get_cinst(struct nouveau_namedb *, u32); +void nouveau_namedb_put(struct nouveau_handle *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h new file mode 100644 index 00000000..62e68bae --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h @@ -0,0 +1,202 @@ +#ifndef __NOUVEAU_OBJECT_H__ +#define __NOUVEAU_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 nouveau_object { + struct nouveau_oclass *oclass; + struct nouveau_object *parent; + struct nouveau_object *engine; + atomic_t refcount; + atomic_t usecount; +#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA +#define NOUVEAU_OBJECT_MAGIC 0x75ef0bad + struct list_head list; + u32 _magic; +#endif +}; + +static inline struct nouveau_object * +nv_object(void *obj) +{ +#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA + if (likely(obj)) { + struct nouveau_object *object = obj; + if (unlikely(object->_magic != NOUVEAU_OBJECT_MAGIC)) + nv_assert("BAD CAST -> NvObject, invalid magic"); + } +#endif + return obj; +} + +#define nouveau_object_create(p,e,c,s,d) \ + nouveau_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d) +int nouveau_object_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u32, int size, void **); +void nouveau_object_destroy(struct nouveau_object *); +int nouveau_object_init(struct nouveau_object *); +int nouveau_object_fini(struct nouveau_object *, bool suspend); + +extern struct nouveau_ofuncs nouveau_object_ofuncs; + +/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in + * ".data". */ +struct nouveau_oclass { + u32 handle; + struct nouveau_ofuncs * const ofuncs; + struct nouveau_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 nouveau_object * +nv_pclass(struct nouveau_object *parent, u32 oclass) +{ + while (parent && !nv_iclass(parent, oclass)) + parent = parent->parent; + return parent; +} + +struct nouveau_omthds { + u32 start; + u32 limit; + int (*call)(struct nouveau_object *, u32, void *, u32); +}; + +struct nouveau_ofuncs { + int (*ctor)(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *data, u32 size, + struct nouveau_object **); + void (*dtor)(struct nouveau_object *); + int (*init)(struct nouveau_object *); + int (*fini)(struct nouveau_object *, bool suspend); + u8 (*rd08)(struct nouveau_object *, u64 offset); + u16 (*rd16)(struct nouveau_object *, u64 offset); + u32 (*rd32)(struct nouveau_object *, u64 offset); + void (*wr08)(struct nouveau_object *, u64 offset, u8 data); + void (*wr16)(struct nouveau_object *, u64 offset, u16 data); + void (*wr32)(struct nouveau_object *, u64 offset, u32 data); +}; + +static inline struct nouveau_ofuncs * +nv_ofuncs(void *obj) +{ + return nv_oclass(obj)->ofuncs; +} + +int nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void nouveau_object_ref(struct nouveau_object *, struct nouveau_object **); +int nouveau_object_inc(struct nouveau_object *); +int nouveau_object_dec(struct nouveau_object *, bool suspend); + +int nouveau_object_new(struct nouveau_object *, u32 parent, u32 handle, + u16 oclass, void *data, u32 size, + struct nouveau_object **); +int nouveau_object_del(struct nouveau_object *, u32 parent, u32 handle); +void nouveau_object_debug(void); + +static inline int +nv_exec(void *obj, u32 mthd, void *data, u32 size) +{ + struct nouveau_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/core/include/core/option.h b/drivers/gpu/drm/nouveau/core/include/core/option.h new file mode 100644 index 00000000..27074957 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/option.h @@ -0,0 +1,11 @@ +#ifndef __NOUVEAU_OPTION_H__ +#define __NOUVEAU_OPTION_H__ + +#include <core/os.h> + +const char *nouveau_stropt(const char *optstr, const char *opt, int *len); +bool nouveau_boolopt(const char *optstr, const char *opt, bool value); + +int nouveau_dbgopt(const char *optstr, const char *sub); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h new file mode 100644 index 00000000..9f5ea900 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/parent.h @@ -0,0 +1,61 @@ +#ifndef __NOUVEAU_PARENT_H__ +#define __NOUVEAU_PARENT_H__ + +#include <core/device.h> +#include <core/object.h> + +struct nouveau_sclass { + struct nouveau_sclass *sclass; + struct nouveau_engine *engine; + struct nouveau_oclass *oclass; +}; + +struct nouveau_parent { + struct nouveau_object base; + + struct nouveau_sclass *sclass; + u64 engine; + + int (*context_attach)(struct nouveau_object *, + struct nouveau_object *); + int (*context_detach)(struct nouveau_object *, bool suspend, + struct nouveau_object *); + + int (*object_attach)(struct nouveau_object *parent, + struct nouveau_object *object, u32 name); + void (*object_detach)(struct nouveau_object *parent, int cookie); +}; + +static inline struct nouveau_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 nouveau_parent_create(p,e,c,v,s,m,d) \ + nouveau_parent_create_((p), (e), (c), (v), (s), (m), \ + sizeof(**d), (void **)d) +#define nouveau_parent_init(p) \ + nouveau_object_init(&(p)->base) +#define nouveau_parent_fini(p,s) \ + nouveau_object_fini(&(p)->base, (s)) + +int nouveau_parent_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u32 pclass, + struct nouveau_oclass *, u64 engcls, + int size, void **); +void nouveau_parent_destroy(struct nouveau_parent *); + +void _nouveau_parent_dtor(struct nouveau_object *); +#define _nouveau_parent_init nouveau_object_init +#define _nouveau_parent_fini nouveau_object_fini + +int nouveau_parent_sclass(struct nouveau_object *, u16 handle, + struct nouveau_object **pengine, + struct nouveau_oclass **poclass); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/printk.h b/drivers/gpu/drm/nouveau/core/include/core/printk.h new file mode 100644 index 00000000..febed2ea --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/printk.h @@ -0,0 +1,40 @@ +#ifndef __NOUVEAU_PRINTK_H__ +#define __NOUVEAU_PRINTK_H__ + +#include <core/os.h> +#include <core/debug.h> + +struct nouveau_object; + +#define NV_PRINTK_FATAL KERN_CRIT +#define NV_PRINTK_ERROR KERN_ERR +#define NV_PRINTK_WARN KERN_WARNING +#define NV_PRINTK_INFO KERN_INFO +#define NV_PRINTK_DEBUG KERN_DEBUG +#define NV_PRINTK_PARANOIA KERN_DEBUG +#define NV_PRINTK_TRACE KERN_DEBUG +#define NV_PRINTK_SPAM KERN_DEBUG + +void __printf(4, 5) +nv_printk_(struct nouveau_object *, const char *, int, const char *, ...); + +#define nv_printk(o,l,f,a...) do { \ + if (NV_DBG_##l <= CONFIG_NOUVEAU_DEBUG) \ + nv_printk_(nv_object(o), NV_PRINTK_##l, 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_assert(f,a...) do { \ + if (NV_DBG_FATAL <= CONFIG_NOUVEAU_DEBUG) \ + nv_printk_(NULL, NV_PRINTK_FATAL, NV_DBG_FATAL, f "\n", ##a); \ + BUG_ON(1); \ +} while(0) + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/ramht.h b/drivers/gpu/drm/nouveau/core/include/core/ramht.h new file mode 100644 index 00000000..47e4cacb --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/ramht.h @@ -0,0 +1,23 @@ +#ifndef __NOUVEAU_RAMHT_H__ +#define __NOUVEAU_RAMHT_H__ + +#include <core/gpuobj.h> + +struct nouveau_ramht { + struct nouveau_gpuobj base; + int bits; +}; + +int nouveau_ramht_insert(struct nouveau_ramht *, int chid, + u32 handle, u32 context); +void nouveau_ramht_remove(struct nouveau_ramht *, int cookie); +int nouveau_ramht_new(struct nouveau_object *, struct nouveau_object *, + u32 size, u32 align, struct nouveau_ramht **); + +static inline void +nouveau_ramht_ref(struct nouveau_ramht *obj, struct nouveau_ramht **ref) +{ + nouveau_gpuobj_ref(&obj->base, (struct nouveau_gpuobj **)ref); +} + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/subdev.h b/drivers/gpu/drm/nouveau/core/include/core/subdev.h new file mode 100644 index 00000000..e9632e93 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/core/subdev.h @@ -0,0 +1,118 @@ +#ifndef __NOUVEAU_SUBDEV_H__ +#define __NOUVEAU_SUBDEV_H__ + +#include <core/object.h> + +#define NV_SUBDEV_(sub,var) (NV_SUBDEV_CLASS | ((var) << 8) | (sub)) +#define NV_SUBDEV(name,var) NV_SUBDEV_(NVDEV_SUBDEV_##name, (var)) + +struct nouveau_subdev { + struct nouveau_object base; + struct mutex mutex; + const char *name; + void __iomem *mmio; + u32 debug; + u32 unit; + + void (*intr)(struct nouveau_subdev *); +}; + +static inline struct nouveau_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 nouveau_object *object) +{ + return nv_hclass(nv_subdev(object)) & 0xff; +} + +#define nouveau_subdev_create(p,e,o,v,s,f,d) \ + nouveau_subdev_create_((p), (e), (o), (v), (s), (f), \ + sizeof(**d),(void **)d) + +int nouveau_subdev_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u32 pclass, + const char *sname, const char *fname, + int size, void **); +void nouveau_subdev_destroy(struct nouveau_subdev *); +int nouveau_subdev_init(struct nouveau_subdev *); +int nouveau_subdev_fini(struct nouveau_subdev *, bool suspend); +void nouveau_subdev_reset(struct nouveau_object *); + +void _nouveau_subdev_dtor(struct nouveau_object *); +int _nouveau_subdev_init(struct nouveau_object *); +int _nouveau_subdev_fini(struct nouveau_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 nouveau_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 nouveau_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 nouveau_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 nouveau_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 nouveau_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 nouveau_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/core/include/engine/bsp.h b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h new file mode 100644 index 00000000..13ccdf54 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h @@ -0,0 +1,8 @@ +#ifndef __NOUVEAU_BSP_H__ +#define __NOUVEAU_BSP_H__ + +extern struct nouveau_oclass nv84_bsp_oclass; +extern struct nouveau_oclass nvc0_bsp_oclass; +extern struct nouveau_oclass nve0_bsp_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/copy.h b/drivers/gpu/drm/nouveau/core/include/engine/copy.h new file mode 100644 index 00000000..8cad2cf2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/copy.h @@ -0,0 +1,12 @@ +#ifndef __NOUVEAU_COPY_H__ +#define __NOUVEAU_COPY_H__ + +void nva3_copy_intr(struct nouveau_subdev *); + +extern struct nouveau_oclass nva3_copy_oclass; +extern struct nouveau_oclass nvc0_copy0_oclass; +extern struct nouveau_oclass nvc0_copy1_oclass; +extern struct nouveau_oclass nve0_copy0_oclass; +extern struct nouveau_oclass nve0_copy1_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/crypt.h b/drivers/gpu/drm/nouveau/core/include/engine/crypt.h new file mode 100644 index 00000000..db975618 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/crypt.h @@ -0,0 +1,7 @@ +#ifndef __NOUVEAU_CRYPT_H__ +#define __NOUVEAU_CRYPT_H__ + +extern struct nouveau_oclass nv84_crypt_oclass; +extern struct nouveau_oclass nv98_crypt_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/device.h b/drivers/gpu/drm/nouveau/core/include/engine/device.h new file mode 100644 index 00000000..b3dd2c4c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/device.h @@ -0,0 +1,23 @@ +#ifndef __NOUVEAU_SUBDEV_DEVICE_H__ +#define __NOUVEAU_SUBDEV_DEVICE_H__ + +#include <core/device.h> + +#define nouveau_device_create(p,n,s,c,d,u) \ + nouveau_device_create_((p), (n), (s), (c), (d), sizeof(**u), (void **)u) + +int nouveau_device_create_(struct pci_dev *, 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 *); + +struct nouveau_device *nouveau_device_find(u64 name); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/disp.h b/drivers/gpu/drm/nouveau/core/include/engine/disp.h new file mode 100644 index 00000000..4b21fabf --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/disp.h @@ -0,0 +1,49 @@ +#ifndef __NOUVEAU_DISP_H__ +#define __NOUVEAU_DISP_H__ + +#include <core/object.h> +#include <core/engine.h> +#include <core/device.h> +#include <core/event.h> + +struct nouveau_disp { + struct nouveau_engine base; + struct nouveau_event *vblank; +}; + +static inline struct nouveau_disp * +nouveau_disp(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_DISP]; +} + +#define nouveau_disp_create(p,e,c,h,i,x,d) \ + nouveau_disp_create_((p), (e), (c), (h), (i), (x), \ + sizeof(**d), (void **)d) +#define nouveau_disp_destroy(d) ({ \ + struct nouveau_disp *disp = (d); \ + _nouveau_disp_dtor(nv_object(disp)); \ +}) +#define nouveau_disp_init(d) \ + nouveau_engine_init(&(d)->base) +#define nouveau_disp_fini(d,s) \ + nouveau_engine_fini(&(d)->base, (s)) + +int nouveau_disp_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int heads, + const char *, const char *, int, void **); +void _nouveau_disp_dtor(struct nouveau_object *); +#define _nouveau_disp_init _nouveau_engine_init +#define _nouveau_disp_fini _nouveau_engine_fini + +extern struct nouveau_oclass nv04_disp_oclass; +extern struct nouveau_oclass nv50_disp_oclass; +extern struct nouveau_oclass nv84_disp_oclass; +extern struct nouveau_oclass nva0_disp_oclass; +extern struct nouveau_oclass nv94_disp_oclass; +extern struct nouveau_oclass nva3_disp_oclass; +extern struct nouveau_oclass nvd0_disp_oclass; +extern struct nouveau_oclass nve0_disp_oclass; +extern struct nouveau_oclass nvf0_disp_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h new file mode 100644 index 00000000..b28914ed --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h @@ -0,0 +1,48 @@ +#ifndef __NOUVEAU_DMAOBJ_H__ +#define __NOUVEAU_DMAOBJ_H__ + +#include <core/object.h> +#include <core/engine.h> + +struct nouveau_gpuobj; + +struct nouveau_dmaobj { + struct nouveau_object base; + u32 target; + u32 access; + u64 start; + u64 limit; + u32 conf0; +}; + +struct nouveau_dmaeng { + struct nouveau_engine base; + + /* creates a "physical" dma object from a struct nouveau_dmaobj */ + int (*bind)(struct nouveau_dmaeng *dmaeng, + struct nouveau_object *parent, + struct nouveau_dmaobj *dmaobj, + struct nouveau_gpuobj **); +}; + +#define nouveau_dmaeng_create(p,e,c,d) \ + nouveau_engine_create((p), (e), (c), true, "DMAOBJ", "dmaobj", (d)) +#define nouveau_dmaeng_destroy(p) \ + nouveau_engine_destroy(&(p)->base) +#define nouveau_dmaeng_init(p) \ + nouveau_engine_init(&(p)->base) +#define nouveau_dmaeng_fini(p,s) \ + nouveau_engine_fini(&(p)->base, (s)) + +#define _nouveau_dmaeng_dtor _nouveau_engine_dtor +#define _nouveau_dmaeng_init _nouveau_engine_init +#define _nouveau_dmaeng_fini _nouveau_engine_fini + +extern struct nouveau_oclass nv04_dmaeng_oclass; +extern struct nouveau_oclass nv50_dmaeng_oclass; +extern struct nouveau_oclass nvc0_dmaeng_oclass; +extern struct nouveau_oclass nvd0_dmaeng_oclass; + +extern struct nouveau_oclass nouveau_dmaobj_sclass[]; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h new file mode 100644 index 00000000..633c2f80 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -0,0 +1,116 @@ +#ifndef __NOUVEAU_FIFO_H__ +#define __NOUVEAU_FIFO_H__ + +#include <core/namedb.h> +#include <core/gpuobj.h> +#include <core/engine.h> + +struct nouveau_fifo_chan { + struct nouveau_namedb base; + struct nouveau_dmaobj *pushdma; + struct nouveau_gpuobj *pushgpu; + void __iomem *user; + u32 size; + u16 chid; + atomic_t refcnt; /* NV04_NVSW_SET_REF */ +}; + +static inline struct nouveau_fifo_chan * +nouveau_fifo_chan(void *obj) +{ + return (void *)nv_namedb(obj); +} + +#define nouveau_fifo_channel_create(p,e,c,b,a,s,n,m,d) \ + nouveau_fifo_channel_create_((p), (e), (c), (b), (a), (s), (n), \ + (m), sizeof(**d), (void **)d) +#define nouveau_fifo_channel_init(p) \ + nouveau_namedb_init(&(p)->base) +#define nouveau_fifo_channel_fini(p,s) \ + nouveau_namedb_fini(&(p)->base, (s)) + +int nouveau_fifo_channel_create_(struct nouveau_object *, + struct nouveau_object *, + struct nouveau_oclass *, + int bar, u32 addr, u32 size, u32 push, + u64 engmask, int len, void **); +void nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *); + +#define _nouveau_fifo_channel_init _nouveau_namedb_init +#define _nouveau_fifo_channel_fini _nouveau_namedb_fini + +void _nouveau_fifo_channel_dtor(struct nouveau_object *); +u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64); +void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32); + +struct nouveau_fifo_base { + struct nouveau_gpuobj base; +}; + +#define nouveau_fifo_context_create(p,e,c,g,s,a,f,d) \ + nouveau_gpuobj_create((p), (e), (c), 0, (g), (s), (a), (f), (d)) +#define nouveau_fifo_context_destroy(p) \ + nouveau_gpuobj_destroy(&(p)->base) +#define nouveau_fifo_context_init(p) \ + nouveau_gpuobj_init(&(p)->base) +#define nouveau_fifo_context_fini(p,s) \ + nouveau_gpuobj_fini(&(p)->base, (s)) + +#define _nouveau_fifo_context_dtor _nouveau_gpuobj_dtor +#define _nouveau_fifo_context_init _nouveau_gpuobj_init +#define _nouveau_fifo_context_fini _nouveau_gpuobj_fini +#define _nouveau_fifo_context_rd32 _nouveau_gpuobj_rd32 +#define _nouveau_fifo_context_wr32 _nouveau_gpuobj_wr32 + +struct nouveau_fifo { + struct nouveau_engine base; + + struct nouveau_event *cevent; /* channel creation event */ + struct nouveau_event *uevent; /* async user trigger */ + + struct nouveau_object **channel; + spinlock_t lock; + u16 min; + u16 max; + + int (*chid)(struct nouveau_fifo *, struct nouveau_object *); + void (*pause)(struct nouveau_fifo *, unsigned long *); + void (*start)(struct nouveau_fifo *, unsigned long *); +}; + +static inline struct nouveau_fifo * +nouveau_fifo(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_FIFO]; +} + +#define nouveau_fifo_create(o,e,c,fc,lc,d) \ + nouveau_fifo_create_((o), (e), (c), (fc), (lc), sizeof(**d), (void **)d) +#define nouveau_fifo_init(p) \ + nouveau_engine_init(&(p)->base) +#define nouveau_fifo_fini(p,s) \ + nouveau_engine_fini(&(p)->base, (s)) + +int nouveau_fifo_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int min, int max, + int size, void **); +void nouveau_fifo_destroy(struct nouveau_fifo *); +const char * +nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid); + +#define _nouveau_fifo_init _nouveau_engine_init +#define _nouveau_fifo_fini _nouveau_engine_fini + +extern struct nouveau_oclass nv04_fifo_oclass; +extern struct nouveau_oclass nv10_fifo_oclass; +extern struct nouveau_oclass nv17_fifo_oclass; +extern struct nouveau_oclass nv40_fifo_oclass; +extern struct nouveau_oclass nv50_fifo_oclass; +extern struct nouveau_oclass nv84_fifo_oclass; +extern struct nouveau_oclass nvc0_fifo_oclass; +extern struct nouveau_oclass nve0_fifo_oclass; + +void nv04_fifo_intr(struct nouveau_subdev *); +int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h new file mode 100644 index 00000000..5d392439 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/graph.h @@ -0,0 +1,76 @@ +#ifndef __NOUVEAU_GRAPH_H__ +#define __NOUVEAU_GRAPH_H__ + +#include <core/engine.h> +#include <core/engctx.h> +#include <core/enum.h> + +struct nouveau_graph_chan { + struct nouveau_engctx base; +}; + +#define nouveau_graph_context_create(p,e,c,g,s,a,f,d) \ + nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d)) +#define nouveau_graph_context_destroy(d) \ + nouveau_engctx_destroy(&(d)->base) +#define nouveau_graph_context_init(d) \ + nouveau_engctx_init(&(d)->base) +#define nouveau_graph_context_fini(d,s) \ + nouveau_engctx_fini(&(d)->base, (s)) + +#define _nouveau_graph_context_dtor _nouveau_engctx_dtor +#define _nouveau_graph_context_init _nouveau_engctx_init +#define _nouveau_graph_context_fini _nouveau_engctx_fini +#define _nouveau_graph_context_rd32 _nouveau_engctx_rd32 +#define _nouveau_graph_context_wr32 _nouveau_engctx_wr32 + +struct nouveau_graph { + struct nouveau_engine base; + + /* Returns chipset-specific counts of units packed into an u64. + */ + u64 (*units)(struct nouveau_graph *); +}; + +static inline struct nouveau_graph * +nouveau_graph(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_GR]; +} + +#define nouveau_graph_create(p,e,c,y,d) \ + nouveau_engine_create((p), (e), (c), (y), "PGRAPH", "graphics", (d)) +#define nouveau_graph_destroy(d) \ + nouveau_engine_destroy(&(d)->base) +#define nouveau_graph_init(d) \ + nouveau_engine_init(&(d)->base) +#define nouveau_graph_fini(d,s) \ + nouveau_engine_fini(&(d)->base, (s)) + +#define _nouveau_graph_dtor _nouveau_engine_dtor +#define _nouveau_graph_init _nouveau_engine_init +#define _nouveau_graph_fini _nouveau_engine_fini + +extern struct nouveau_oclass nv04_graph_oclass; +extern struct nouveau_oclass nv10_graph_oclass; +extern struct nouveau_oclass nv20_graph_oclass; +extern struct nouveau_oclass nv25_graph_oclass; +extern struct nouveau_oclass nv2a_graph_oclass; +extern struct nouveau_oclass nv30_graph_oclass; +extern struct nouveau_oclass nv34_graph_oclass; +extern struct nouveau_oclass nv35_graph_oclass; +extern struct nouveau_oclass nv40_graph_oclass; +extern struct nouveau_oclass nv50_graph_oclass; +extern struct nouveau_oclass nvc0_graph_oclass; +extern struct nouveau_oclass nve0_graph_oclass; + +extern const struct nouveau_bitfield nv04_graph_nsource[]; +extern struct nouveau_ofuncs nv04_graph_ofuncs; +bool nv04_graph_idle(void *obj); + +extern const struct nouveau_bitfield nv10_graph_intr_name[]; +extern const struct nouveau_bitfield nv10_graph_nstatus[]; + +extern const struct nouveau_enum nv50_data_error_names[]; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h new file mode 100644 index 00000000..bbf0d4a5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h @@ -0,0 +1,61 @@ +#ifndef __NOUVEAU_MPEG_H__ +#define __NOUVEAU_MPEG_H__ + +#include <core/engine.h> +#include <core/engctx.h> + +struct nouveau_mpeg_chan { + struct nouveau_engctx base; +}; + +#define nouveau_mpeg_context_create(p,e,c,g,s,a,f,d) \ + nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d)) +#define nouveau_mpeg_context_destroy(d) \ + nouveau_engctx_destroy(&(d)->base) +#define nouveau_mpeg_context_init(d) \ + nouveau_engctx_init(&(d)->base) +#define nouveau_mpeg_context_fini(d,s) \ + nouveau_engctx_fini(&(d)->base, (s)) + +#define _nouveau_mpeg_context_dtor _nouveau_engctx_dtor +#define _nouveau_mpeg_context_init _nouveau_engctx_init +#define _nouveau_mpeg_context_fini _nouveau_engctx_fini +#define _nouveau_mpeg_context_rd32 _nouveau_engctx_rd32 +#define _nouveau_mpeg_context_wr32 _nouveau_engctx_wr32 + +struct nouveau_mpeg { + struct nouveau_engine base; +}; + +#define nouveau_mpeg_create(p,e,c,d) \ + nouveau_engine_create((p), (e), (c), true, "PMPEG", "mpeg", (d)) +#define nouveau_mpeg_destroy(d) \ + nouveau_engine_destroy(&(d)->base) +#define nouveau_mpeg_init(d) \ + nouveau_engine_init(&(d)->base) +#define nouveau_mpeg_fini(d,s) \ + nouveau_engine_fini(&(d)->base, (s)) + +#define _nouveau_mpeg_dtor _nouveau_engine_dtor +#define _nouveau_mpeg_init _nouveau_engine_init +#define _nouveau_mpeg_fini _nouveau_engine_fini + +extern struct nouveau_oclass nv31_mpeg_oclass; +extern struct nouveau_oclass nv40_mpeg_oclass; +extern struct nouveau_oclass nv50_mpeg_oclass; +extern struct nouveau_oclass nv84_mpeg_oclass; + +extern struct nouveau_oclass nv31_mpeg_sclass[]; +void nv31_mpeg_intr(struct nouveau_subdev *); +void nv31_mpeg_tile_prog(struct nouveau_engine *, int); +int nv31_mpeg_init(struct nouveau_object *); + +extern struct nouveau_ofuncs nv50_mpeg_ofuncs; +int nv50_mpeg_context_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +int nv50_mpeg_tlb_flush(struct nouveau_engine *); +void nv50_mpeg_intr(struct nouveau_subdev *); +int nv50_mpeg_init(struct nouveau_object *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/ppp.h b/drivers/gpu/drm/nouveau/core/include/engine/ppp.h new file mode 100644 index 00000000..0a66781e --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/ppp.h @@ -0,0 +1,7 @@ +#ifndef __NOUVEAU_PPP_H__ +#define __NOUVEAU_PPP_H__ + +extern struct nouveau_oclass nv98_ppp_oclass; +extern struct nouveau_oclass nvc0_ppp_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/software.h b/drivers/gpu/drm/nouveau/core/include/engine/software.h new file mode 100644 index 00000000..45799487 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/software.h @@ -0,0 +1,60 @@ +#ifndef __NOUVEAU_SOFTWARE_H__ +#define __NOUVEAU_SOFTWARE_H__ + +#include <core/engine.h> +#include <core/engctx.h> +#include <core/event.h> + +struct nouveau_software_chan { + struct nouveau_engctx base; + + struct { + struct nouveau_eventh event; + u32 channel; + u32 ctxdma; + u64 offset; + u32 value; + } vblank; + + int (*flip)(void *); + void *flip_data; +}; + +#define nouveau_software_context_create(p,e,c,d) \ + nouveau_engctx_create((p), (e), (c), (p), 0, 0, 0, (d)) +#define nouveau_software_context_destroy(d) \ + nouveau_engctx_destroy(&(d)->base) +#define nouveau_software_context_init(d) \ + nouveau_engctx_init(&(d)->base) +#define nouveau_software_context_fini(d,s) \ + nouveau_engctx_fini(&(d)->base, (s)) + +#define _nouveau_software_context_dtor _nouveau_engctx_dtor +#define _nouveau_software_context_init _nouveau_engctx_init +#define _nouveau_software_context_fini _nouveau_engctx_fini + +struct nouveau_software { + struct nouveau_engine base; +}; + +#define nouveau_software_create(p,e,c,d) \ + nouveau_engine_create((p), (e), (c), true, "SW", "software", (d)) +#define nouveau_software_destroy(d) \ + nouveau_engine_destroy(&(d)->base) +#define nouveau_software_init(d) \ + nouveau_engine_init(&(d)->base) +#define nouveau_software_fini(d,s) \ + nouveau_engine_fini(&(d)->base, (s)) + +#define _nouveau_software_dtor _nouveau_engine_dtor +#define _nouveau_software_init _nouveau_engine_init +#define _nouveau_software_fini _nouveau_engine_fini + +extern struct nouveau_oclass nv04_software_oclass; +extern struct nouveau_oclass nv10_software_oclass; +extern struct nouveau_oclass nv50_software_oclass; +extern struct nouveau_oclass nvc0_software_oclass; + +void nv04_software_intr(struct nouveau_subdev *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/vp.h b/drivers/gpu/drm/nouveau/core/include/engine/vp.h new file mode 100644 index 00000000..d7b287b1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/vp.h @@ -0,0 +1,8 @@ +#ifndef __NOUVEAU_VP_H__ +#define __NOUVEAU_VP_H__ + +extern struct nouveau_oclass nv84_vp_oclass; +extern struct nouveau_oclass nvc0_vp_oclass; +extern struct nouveau_oclass nve0_vp_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bar.h b/drivers/gpu/drm/nouveau/core/include/subdev/bar.h new file mode 100644 index 00000000..4f4ff450 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bar.h @@ -0,0 +1,55 @@ +#ifndef __NOUVEAU_BAR_H__ +#define __NOUVEAU_BAR_H__ + +#include <core/subdev.h> +#include <core/device.h> + +#include <subdev/fb.h> + +struct nouveau_vma; + +struct nouveau_bar { + struct nouveau_subdev base; + + int (*alloc)(struct nouveau_bar *, struct nouveau_object *, + struct nouveau_mem *, struct nouveau_object **); + void __iomem *iomem; + + int (*kmap)(struct nouveau_bar *, struct nouveau_mem *, + u32 flags, struct nouveau_vma *); + int (*umap)(struct nouveau_bar *, struct nouveau_mem *, + u32 flags, struct nouveau_vma *); + void (*unmap)(struct nouveau_bar *, struct nouveau_vma *); + void (*flush)(struct nouveau_bar *); +}; + +static inline struct nouveau_bar * +nouveau_bar(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_BAR]; +} + +#define nouveau_bar_create(p,e,o,d) \ + nouveau_bar_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_bar_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_bar_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +int nouveau_bar_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +void nouveau_bar_destroy(struct nouveau_bar *); + +void _nouveau_bar_dtor(struct nouveau_object *); +#define _nouveau_bar_init _nouveau_subdev_init +#define _nouveau_bar_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nv50_bar_oclass; +extern struct nouveau_oclass nvc0_bar_oclass; + +int nouveau_bar_alloc(struct nouveau_bar *, struct nouveau_object *, + struct nouveau_mem *, struct nouveau_object **); + +void nv84_bar_flush(struct nouveau_bar *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h new file mode 100644 index 00000000..5bd1ca8c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h @@ -0,0 +1,35 @@ +#ifndef __NOUVEAU_BIOS_H__ +#define __NOUVEAU_BIOS_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_bios { + struct nouveau_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 nouveau_bios * +nouveau_bios(void *obj) +{ + return (void *)nv_device(obj)->subdev[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 nouveau_oclass nouveau_bios_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h new file mode 100644 index 00000000..73f060b0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h @@ -0,0 +1,13 @@ +#ifndef __NVBIOS_BIT_H__ +#define __NVBIOS_BIT_H__ + +struct bit_entry { + u8 id; + u8 version; + u16 length; + u16 offset; +}; + +int bit_entry(struct nouveau_bios *, u8 id, struct bit_entry *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h new file mode 100644 index 00000000..10e4dbca --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h @@ -0,0 +1,39 @@ +#ifndef __NVBIOS_BMP_H__ +#define __NVBIOS_BMP_H__ + +static inline u16 +bmp_version(struct nouveau_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 nouveau_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 nouveau_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 nouveau_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/core/include/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h new file mode 100644 index 00000000..c1270548 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h @@ -0,0 +1,27 @@ +#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_DMS59_DP0 = 0x64, + DCB_CONNECTOR_DMS59_DP1 = 0x65, + DCB_CONNECTOR_NONE = 0xff +}; + +u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h new file mode 100644 index 00000000..123270e9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h @@ -0,0 +1,69 @@ +#ifndef __NVBIOS_DCB_H__ +#define __NVBIOS_DCB_H__ + +struct nouveau_bios; + +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 nouveau_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len); +u16 dcb_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len); +u16 dcb_outp_parse(struct nouveau_bios *, u8 idx, u8 *, u8 *, + struct dcb_output *); +u16 dcb_outp_match(struct nouveau_bios *, u16 type, u16 mask, u8 *, u8 *, + struct dcb_output *); +int dcb_outp_foreach(struct nouveau_bios *, void *data, int (*exec) + (struct nouveau_bios *, void *, int index, u16 entry)); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h new file mode 100644 index 00000000..c35937e2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h @@ -0,0 +1,48 @@ +#ifndef __NVBIOS_DISP_H__ +#define __NVBIOS_DISP_H__ + +u16 nvbios_disp_table(struct nouveau_bios *, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub); + +struct nvbios_disp { + u16 data; +}; + +u16 nvbios_disp_entry(struct nouveau_bios *, u8 idx, + u8 *ver, u8 *hdr__, u8 *sub); +u16 nvbios_disp_parse(struct nouveau_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 nouveau_bios *, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u16 nvbios_outp_parse(struct nouveau_bios *, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_outp *); +u16 nvbios_outp_match(struct nouveau_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 nouveau_bios *, u16 outp, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u16 nvbios_ocfg_parse(struct nouveau_bios *, u16 outp, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_ocfg *); +u16 nvbios_ocfg_match(struct nouveau_bios *, u16 outp, u16 type, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_ocfg *); +u16 nvbios_oclk_match(struct nouveau_bios *, u16 cmp, u32 khz); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h new file mode 100644 index 00000000..6e54218b --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h @@ -0,0 +1,34 @@ +#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 nouveau_bios *, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_dpout *); +u16 nvbios_dpout_match(struct nouveau_bios *, u16 type, u16 mask, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_dpout *); + +struct nvbios_dpcfg { + u8 drv; + u8 pre; + u8 unk; +}; + +u16 +nvbios_dpcfg_parse(struct nouveau_bios *, u16 outp, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_dpcfg *); +u16 +nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 un, u8 vs, u8 pe, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_dpcfg *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h new file mode 100644 index 00000000..949fee3a --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h @@ -0,0 +1,30 @@ +#ifndef __NVBIOS_EXTDEV_H__ +#define __NVBIOS_EXTDEV_H__ + +struct nouveau_bios; + +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 nouveau_bios *, int, struct nvbios_extdev_func *); + +int +nvbios_extdev_find(struct nouveau_bios *, enum nvbios_extdev_type, + struct nvbios_extdev_func *); + + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h new file mode 100644 index 00000000..96d3364f --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h @@ -0,0 +1,40 @@ +#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 +}; + +#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 nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len); +u16 dcb_gpio_parse(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len, + struct dcb_gpio_func *); +u16 dcb_gpio_match(struct nouveau_bios *, int idx, u8 func, u8 line, + u8 *ver, u8 *len, struct dcb_gpio_func *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h new file mode 100644 index 00000000..10b57a19 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h @@ -0,0 +1,25 @@ +#ifndef __NVBIOS_I2C_H__ +#define __NVBIOS_I2C_H__ + +struct nouveau_bios; + +enum dcb_i2c_type { + DCB_I2C_NV04_BIT = 0, + DCB_I2C_NV4E_BIT = 4, + DCB_I2C_NVIO_BIT = 5, + DCB_I2C_NVIO_AUX = 6, + DCB_I2C_UNUSED = 0xff +}; + +struct dcb_i2c_entry { + enum dcb_i2c_type type; + u8 drive; + u8 sense; + u8 share; +}; + +u16 dcb_i2c_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u16 dcb_i2c_entry(struct nouveau_bios *, u8 index, u8 *ver, u8 *len); +int dcb_i2c_parse(struct nouveau_bios *, u8 index, struct dcb_i2c_entry *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h new file mode 100644 index 00000000..ca2f6bf3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h @@ -0,0 +1,22 @@ +#ifndef __NVBIOS_INIT_H__ +#define __NVBIOS_INIT_H__ + +struct nvbios_init { + struct nouveau_subdev *subdev; + struct nouveau_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 nouveau_subdev *, bool execute); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h new file mode 100644 index 00000000..5572e604 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h @@ -0,0 +1,9 @@ +#ifndef __NVBIOS_MXM_H__ +#define __NVBIOS_MXM_H__ + +u16 mxm_table(struct nouveau_bios *, u8 *ver, u8 *hdr); + +u8 mxm_sor_map(struct nouveau_bios *, u8 conn); +u8 mxm_ddc_map(struct nouveau_bios *, u8 port); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h new file mode 100644 index 00000000..0b285e99 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h @@ -0,0 +1,14 @@ +#ifndef __NVBIOS_PERF_H__ +#define __NVBIOS_PERF_H__ + +struct nouveau_bios; + +struct nvbios_perf_fan { + u32 pwm_divisor; +}; + +int +nvbios_perf_fan_parse(struct nouveau_bios *, struct nvbios_perf_fan *); + + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h new file mode 100644 index 00000000..b2f3d4d0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h @@ -0,0 +1,79 @@ +#ifndef __NVBIOS_PLL_H__ +#define __NVBIOS_PLL_H__ + +/*XXX: kill me */ +struct nouveau_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; +}; + +struct nouveau_bios; + +/* these match types in pll limits table version 0x40, + * nouveau 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 nouveau_bios *, u32 type, struct nvbios_pll *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h new file mode 100644 index 00000000..083541db --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h @@ -0,0 +1,62 @@ +#ifndef __NVBIOS_THERM_H__ +#define __NVBIOS_THERM_H__ + +struct nouveau_bios; + +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; +}; + +/* no vbios have more than 6 */ +#define NOUVEAU_TEMP_FAN_TRIP_MAX 10 +struct nouveau_therm_trip_point { + int fan_duty; + int temp; + int hysteresis; +}; + +struct nvbios_therm_fan { + u16 pwm_freq; + + u8 min_duty; + u8 max_duty; + + u16 bump_period; + u16 slow_down_period; + + struct nouveau_therm_trip_point trip[NOUVEAU_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 nouveau_bios *, enum nvbios_therm_domain, + struct nvbios_therm_sensor *); + +int +nvbios_therm_fan_parse(struct nouveau_bios *, struct nvbios_therm_fan *); + + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h new file mode 100644 index 00000000..360baab5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h @@ -0,0 +1,19 @@ +#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 nouveau_bios *, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u16 dcb_xpio_parse(struct nouveau_bios *, u8 idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h new file mode 100644 index 00000000..7d88ec4a --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h @@ -0,0 +1,41 @@ +#ifndef __NOUVEAU_BUS_H__ +#define __NOUVEAU_BUS_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_bus_intr { + u32 stat; + u32 unit; +}; + +struct nouveau_bus { + struct nouveau_subdev base; +}; + +static inline struct nouveau_bus * +nouveau_bus(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_BUS]; +} + +#define nouveau_bus_create(p, e, o, d) \ + nouveau_subdev_create_((p), (e), (o), 0, "PBUS", "master", \ + sizeof(**d), (void **)d) +#define nouveau_bus_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_bus_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_bus_fini(p, s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +#define _nouveau_bus_dtor _nouveau_subdev_dtor +#define _nouveau_bus_init _nouveau_subdev_init +#define _nouveau_bus_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nv04_bus_oclass; +extern struct nouveau_oclass nv31_bus_oclass; +extern struct nouveau_oclass nv50_bus_oclass; +extern struct nouveau_oclass nvc0_bus_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h new file mode 100644 index 00000000..41b7a6a7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h @@ -0,0 +1,60 @@ +#ifndef __NOUVEAU_CLOCK_H__ +#define __NOUVEAU_CLOCK_H__ + +#include <core/device.h> +#include <core/subdev.h> + +struct nouveau_pll_vals; +struct nvbios_pll; + +struct nouveau_clock { + struct nouveau_subdev base; + + int (*pll_set)(struct nouveau_clock *, u32 type, u32 freq); + + /*XXX: die, these are here *only* to support the completely + * bat-shit insane what-was-nouveau_hw.c code + */ + int (*pll_calc)(struct nouveau_clock *, struct nvbios_pll *, + int clk, struct nouveau_pll_vals *pv); + int (*pll_prog)(struct nouveau_clock *, u32 reg1, + struct nouveau_pll_vals *pv); +}; + +static inline struct nouveau_clock * +nouveau_clock(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK]; +} + +#define nouveau_clock_create(p,e,o,d) \ + nouveau_subdev_create((p), (e), (o), 0, "CLOCK", "clock", d) +#define nouveau_clock_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_clock_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_clock_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, int, void **); + +#define _nouveau_clock_dtor _nouveau_subdev_dtor +#define _nouveau_clock_init _nouveau_subdev_init +#define _nouveau_clock_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nv04_clock_oclass; +extern struct nouveau_oclass nv40_clock_oclass; +extern struct nouveau_oclass nv50_clock_oclass; +extern struct nouveau_oclass nva3_clock_oclass; +extern struct nouveau_oclass nvc0_clock_oclass; + +int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq); +int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, + int clk, struct nouveau_pll_vals *); +int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, + struct nouveau_pll_vals *); +int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, + int clk, struct nouveau_pll_vals *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h new file mode 100644 index 00000000..29e4cc1f --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h @@ -0,0 +1,40 @@ +#ifndef __NOUVEAU_DEVINIT_H__ +#define __NOUVEAU_DEVINIT_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_devinit { + struct nouveau_subdev base; + bool post; + void (*meminit)(struct nouveau_devinit *); +}; + +static inline struct nouveau_devinit * +nouveau_devinit(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_DEVINIT]; +} + +#define nouveau_devinit_create(p,e,o,d) \ + nouveau_devinit_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_devinit_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) + +int nouveau_devinit_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +int nouveau_devinit_init(struct nouveau_devinit *); +int nouveau_devinit_fini(struct nouveau_devinit *, bool suspend); + +extern struct nouveau_oclass nv04_devinit_oclass; +extern struct nouveau_oclass nv05_devinit_oclass; +extern struct nouveau_oclass nv10_devinit_oclass; +extern struct nouveau_oclass nv1a_devinit_oclass; +extern struct nouveau_oclass nv20_devinit_oclass; +extern struct nouveau_oclass nv50_devinit_oclass; + +void nv04_devinit_dtor(struct nouveau_object *); +int nv04_devinit_init(struct nouveau_object *); +int nv04_devinit_fini(struct nouveau_object *, bool); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h new file mode 100644 index 00000000..da470e68 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h @@ -0,0 +1,171 @@ +#ifndef __NOUVEAU_FB_H__ +#define __NOUVEAU_FB_H__ + +#include <core/subdev.h> +#include <core/device.h> +#include <core/mm.h> + +#include <subdev/vm.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 nouveau_mem { + struct drm_device *dev; + + struct nouveau_vma bar_vma; + struct nouveau_vma vma[2]; + u8 page_shift; + + struct nouveau_mm_node *tag; + struct list_head regions; + dma_addr_t *pages; + u32 memtype; + u64 offset; + u64 size; + struct sg_table *sg; +}; + +struct nouveau_fb_tile { + struct nouveau_mm_node *tag; + u32 addr; + u32 limit; + u32 pitch; + u32 zcomp; +}; + +struct nouveau_fb { + struct nouveau_subdev base; + + bool (*memtype_valid)(struct nouveau_fb *, u32 memtype); + + struct { + 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; + + int ranks; + int parts; + + int (*init)(struct nouveau_fb *); + int (*get)(struct nouveau_fb *, u64 size, u32 align, + u32 size_nc, u32 type, struct nouveau_mem **); + void (*put)(struct nouveau_fb *, struct nouveau_mem **); + } ram; + + struct nouveau_mm vram; + struct nouveau_mm tags; + + struct { + struct nouveau_fb_tile region[16]; + int regions; + void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); + void (*comp)(struct nouveau_fb *, int i, u32 size, u32 flags, + struct nouveau_fb_tile *); + void (*fini)(struct nouveau_fb *, int i, + struct nouveau_fb_tile *); + void (*prog)(struct nouveau_fb *, int i, + struct nouveau_fb_tile *); + } tile; +}; + +static inline struct nouveau_fb * +nouveau_fb(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB]; +} + +#define nouveau_fb_create(p,e,c,d) \ + nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d)) +int nouveau_fb_preinit(struct nouveau_fb *); +void nouveau_fb_destroy(struct nouveau_fb *); +int nouveau_fb_init(struct nouveau_fb *); +#define nouveau_fb_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +void _nouveau_fb_dtor(struct nouveau_object *); +int _nouveau_fb_init(struct nouveau_object *); +#define _nouveau_fb_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nv04_fb_oclass; +extern struct nouveau_oclass nv10_fb_oclass; +extern struct nouveau_oclass nv1a_fb_oclass; +extern struct nouveau_oclass nv20_fb_oclass; +extern struct nouveau_oclass nv25_fb_oclass; +extern struct nouveau_oclass nv30_fb_oclass; +extern struct nouveau_oclass nv35_fb_oclass; +extern struct nouveau_oclass nv36_fb_oclass; +extern struct nouveau_oclass nv40_fb_oclass; +extern struct nouveau_oclass nv41_fb_oclass; +extern struct nouveau_oclass nv44_fb_oclass; +extern struct nouveau_oclass nv46_fb_oclass; +extern struct nouveau_oclass nv47_fb_oclass; +extern struct nouveau_oclass nv49_fb_oclass; +extern struct nouveau_oclass nv4e_fb_oclass; +extern struct nouveau_oclass nv50_fb_oclass; +extern struct nouveau_oclass nvc0_fb_oclass; + +struct nouveau_bios; +int nouveau_fb_bios_memtype(struct nouveau_bios *); + +bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype); + +void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); +void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *); +void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +int nv20_fb_vram_init(struct nouveau_fb *); +void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); +void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *); +void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +int nv30_fb_init(struct nouveau_object *); +void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); + +void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags, + struct nouveau_fb_tile *); + +int nv41_fb_vram_init(struct nouveau_fb *); +int nv41_fb_init(struct nouveau_object *); +void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +int nv44_fb_vram_init(struct nouveau_fb *); +int nv44_fb_init(struct nouveau_object *); +void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); + +void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h new file mode 100644 index 00000000..c85b9f15 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h @@ -0,0 +1,53 @@ +#ifndef __NOUVEAU_GPIO_H__ +#define __NOUVEAU_GPIO_H__ + +#include <core/subdev.h> +#include <core/device.h> +#include <core/event.h> + +#include <subdev/bios.h> +#include <subdev/bios/gpio.h> + +struct nouveau_gpio { + struct nouveau_subdev base; + + struct nouveau_event *events; + + /* hardware interfaces */ + void (*reset)(struct nouveau_gpio *, u8 func); + int (*drive)(struct nouveau_gpio *, int line, int dir, int out); + int (*sense)(struct nouveau_gpio *, int line); + + /* software interfaces */ + int (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line, + struct dcb_gpio_func *); + int (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state); + int (*get)(struct nouveau_gpio *, int idx, u8 tag, u8 line); +}; + +static inline struct nouveau_gpio * +nouveau_gpio(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_GPIO]; +} + +#define nouveau_gpio_create(p,e,o,l,d) \ + nouveau_gpio_create_((p), (e), (o), (l), sizeof(**d), (void **)d) +#define nouveau_gpio_destroy(p) ({ \ + struct nouveau_gpio *gpio = (p); \ + _nouveau_gpio_dtor(nv_object(gpio)); \ +}) +#define nouveau_gpio_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, int, void **); +void _nouveau_gpio_dtor(struct nouveau_object *); +int nouveau_gpio_init(struct nouveau_gpio *); + +extern struct nouveau_oclass nv10_gpio_oclass; +extern struct nouveau_oclass nv50_gpio_oclass; +extern struct nouveau_oclass nvd0_gpio_oclass; +extern struct nouveau_oclass nve0_gpio_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h new file mode 100644 index 00000000..888384c0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h @@ -0,0 +1,151 @@ +#ifndef __NOUVEAU_I2C_H__ +#define __NOUVEAU_I2C_H__ + +#include <core/subdev.h> +#include <core/device.h> + +#include <subdev/bios.h> +#include <subdev/bios/i2c.h> + +#define NV_I2C_PORT(n) (0x00 + (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 nouveau_i2c_port { + struct nouveau_object base; + struct i2c_adapter adapter; + + struct list_head head; + u8 index; + + const struct nouveau_i2c_func *func; +}; + +struct nouveau_i2c_func { + void (*acquire)(struct nouveau_i2c_port *); + void (*release)(struct nouveau_i2c_port *); + + void (*drive_scl)(struct nouveau_i2c_port *, int); + void (*drive_sda)(struct nouveau_i2c_port *, int); + int (*sense_scl)(struct nouveau_i2c_port *); + int (*sense_sda)(struct nouveau_i2c_port *); + + int (*aux)(struct nouveau_i2c_port *, u8, u32, u8 *, u8); + int (*pattern)(struct nouveau_i2c_port *, int pattern); + int (*lnk_ctl)(struct nouveau_i2c_port *, int nr, int bw, bool enh); + int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe); +}; + +#define nouveau_i2c_port_create(p,e,o,i,a,d) \ + nouveau_i2c_port_create_((p), (e), (o), (i), (a), \ + sizeof(**d), (void **)d) +#define nouveau_i2c_port_destroy(p) ({ \ + struct nouveau_i2c_port *port = (p); \ + _nouveau_i2c_port_dtor(nv_object(i2c)); \ +}) +#define nouveau_i2c_port_init(p) \ + nouveau_object_init(&(p)->base) +#define nouveau_i2c_port_fini(p,s) \ + nouveau_object_fini(&(p)->base, (s)) + +int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u8, + const struct i2c_algorithm *, int, void **); +void _nouveau_i2c_port_dtor(struct nouveau_object *); +#define _nouveau_i2c_port_init nouveau_object_init +#define _nouveau_i2c_port_fini nouveau_object_fini + +struct nouveau_i2c { + struct nouveau_subdev base; + + struct nouveau_i2c_port *(*find)(struct nouveau_i2c *, u8 index); + struct nouveau_i2c_port *(*find_type)(struct nouveau_i2c *, u16 type); + int (*identify)(struct nouveau_i2c *, int index, + const char *what, struct i2c_board_info *, + bool (*match)(struct nouveau_i2c_port *, + struct i2c_board_info *)); + struct list_head ports; +}; + +static inline struct nouveau_i2c * +nouveau_i2c(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_I2C]; +} + +#define nouveau_i2c_create(p,e,o,s,d) \ + nouveau_i2c_create_((p), (e), (o), (s), sizeof(**d), (void **)d) +#define nouveau_i2c_destroy(p) ({ \ + struct nouveau_i2c *i2c = (p); \ + _nouveau_i2c_dtor(nv_object(i2c)); \ +}) +#define nouveau_i2c_init(p) ({ \ + struct nouveau_i2c *i2c = (p); \ + _nouveau_i2c_init(nv_object(i2c)); \ +}) +#define nouveau_i2c_fini(p,s) ({ \ + struct nouveau_i2c *i2c = (p); \ + _nouveau_i2c_fini(nv_object(i2c), (s)); \ +}) + +int nouveau_i2c_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, struct nouveau_oclass *, + int, void **); +void _nouveau_i2c_dtor(struct nouveau_object *); +int _nouveau_i2c_init(struct nouveau_object *); +int _nouveau_i2c_fini(struct nouveau_object *, bool); + +extern struct nouveau_oclass nv04_i2c_oclass; +extern struct nouveau_oclass nv4e_i2c_oclass; +extern struct nouveau_oclass nv50_i2c_oclass; +extern struct nouveau_oclass nv94_i2c_oclass; +extern struct nouveau_oclass nvd0_i2c_oclass; +extern struct nouveau_oclass nouveau_anx9805_sclass[]; + +extern const struct i2c_algorithm nouveau_i2c_bit_algo; +extern const struct i2c_algorithm nouveau_i2c_aux_algo; + +static inline int +nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg) +{ + u8 val; + struct i2c_msg msgs[] = { + { .addr = addr, .flags = 0, .len = 1, .buf = ® }, + { .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 nouveau_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 nouveau_i2c_port *port, u8 addr) +{ + return nv_rdi2cr(port, addr, 0) >= 0; +} + +int nv_rdaux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size); +int nv_wraux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h new file mode 100644 index 00000000..88814f15 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h @@ -0,0 +1,34 @@ +#ifndef __NOUVEAU_IBUS_H__ +#define __NOUVEAU_IBUS_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_ibus { + struct nouveau_subdev base; +}; + +static inline struct nouveau_ibus * +nouveau_ibus(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_IBUS]; +} + +#define nouveau_ibus_create(p,e,o,d) \ + nouveau_subdev_create_((p), (e), (o), 0, "PIBUS", "ibus", \ + sizeof(**d), (void **)d) +#define nouveau_ibus_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_ibus_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_ibus_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +#define _nouveau_ibus_dtor _nouveau_subdev_dtor +#define _nouveau_ibus_init _nouveau_subdev_init +#define _nouveau_ibus_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nvc0_ibus_oclass; +extern struct nouveau_oclass nve0_ibus_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h new file mode 100644 index 00000000..ec7a54e9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h @@ -0,0 +1,73 @@ +#ifndef __NOUVEAU_INSTMEM_H__ +#define __NOUVEAU_INSTMEM_H__ + +#include <core/subdev.h> +#include <core/device.h> +#include <core/mm.h> + +struct nouveau_instobj { + struct nouveau_object base; + struct list_head head; + u32 *suspend; + u64 addr; + u32 size; +}; + +static inline struct nouveau_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; +} + +#define nouveau_instobj_create(p,e,o,d) \ + nouveau_instobj_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_instobj_init(p) \ + nouveau_object_init(&(p)->base) +#define nouveau_instobj_fini(p,s) \ + nouveau_object_fini(&(p)->base, (s)) + +int nouveau_instobj_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +void nouveau_instobj_destroy(struct nouveau_instobj *); + +void _nouveau_instobj_dtor(struct nouveau_object *); +#define _nouveau_instobj_init nouveau_object_init +#define _nouveau_instobj_fini nouveau_object_fini + +struct nouveau_instmem { + struct nouveau_subdev base; + struct list_head list; + + u32 reserved; + int (*alloc)(struct nouveau_instmem *, struct nouveau_object *, + u32 size, u32 align, struct nouveau_object **); +}; + +static inline struct nouveau_instmem * +nouveau_instmem(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_INSTMEM]; +} + +#define nouveau_instmem_create(p,e,o,d) \ + nouveau_instmem_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_instmem_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +int nouveau_instmem_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +int nouveau_instmem_init(struct nouveau_instmem *); +int nouveau_instmem_fini(struct nouveau_instmem *, bool); + +#define _nouveau_instmem_dtor _nouveau_subdev_dtor +int _nouveau_instmem_init(struct nouveau_object *); +int _nouveau_instmem_fini(struct nouveau_object *, bool); + +extern struct nouveau_oclass nv04_instmem_oclass; +extern struct nouveau_oclass nv40_instmem_oclass; +extern struct nouveau_oclass nv50_instmem_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h new file mode 100644 index 00000000..a1985ed3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h @@ -0,0 +1,40 @@ +#ifndef __NOUVEAU_LTCG_H__ +#define __NOUVEAU_LTCG_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_mm_node; + +struct nouveau_ltcg { + struct nouveau_subdev base; + + int (*tags_alloc)(struct nouveau_ltcg *, u32 count, + struct nouveau_mm_node **); + void (*tags_free)(struct nouveau_ltcg *, struct nouveau_mm_node **); + void (*tags_clear)(struct nouveau_ltcg *, u32 first, u32 count); +}; + +static inline struct nouveau_ltcg * +nouveau_ltcg(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_LTCG]; +} + +#define nouveau_ltcg_create(p,e,o,d) \ + nouveau_subdev_create_((p), (e), (o), 0, "PLTCG", "level2", \ + sizeof(**d), (void **)d) +#define nouveau_ltcg_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_ltcg_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_ltcg_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +#define _nouveau_ltcg_dtor _nouveau_subdev_dtor +#define _nouveau_ltcg_init _nouveau_subdev_init +#define _nouveau_ltcg_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nvc0_ltcg_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h new file mode 100644 index 00000000..9d2cd200 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h @@ -0,0 +1,52 @@ +#ifndef __NOUVEAU_MC_H__ +#define __NOUVEAU_MC_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_mc_intr { + u32 stat; + u32 unit; +}; + +struct nouveau_mc { + struct nouveau_subdev base; + const struct nouveau_mc_intr *intr_map; +}; + +static inline struct nouveau_mc * +nouveau_mc(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC]; +} + +#define nouveau_mc_create(p,e,o,m,d) \ + nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d) +#define nouveau_mc_destroy(p) ({ \ + struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \ +}) +#define nouveau_mc_init(p) ({ \ + struct nouveau_mc *pmc = (p); _nouveau_mc_init(nv_object(pmc)); \ +}) +#define nouveau_mc_fini(p,s) ({ \ + struct nouveau_mc *pmc = (p); _nouveau_mc_fini(nv_object(pmc), (s)); \ +}) + +int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, const struct nouveau_mc_intr *, + int, void **); +void _nouveau_mc_dtor(struct nouveau_object *); +int _nouveau_mc_init(struct nouveau_object *); +int _nouveau_mc_fini(struct nouveau_object *, bool); + +extern struct nouveau_oclass nv04_mc_oclass; +extern struct nouveau_oclass nv44_mc_oclass; +extern struct nouveau_oclass nv50_mc_oclass; +extern struct nouveau_oclass nv98_mc_oclass; +extern struct nouveau_oclass nvc0_mc_oclass; + +extern const struct nouveau_mc_intr nv04_mc_intr[]; +int nv04_mc_init(struct nouveau_object *); +int nv50_mc_init(struct nouveau_object *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h b/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h new file mode 100644 index 00000000..b93b152c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h @@ -0,0 +1,37 @@ +#ifndef __NOUVEAU_MXM_H__ +#define __NOUVEAU_MXM_H__ + +#include <core/subdev.h> +#include <core/device.h> + +#define MXM_SANITISE_DCB 0x00000001 + +struct nouveau_mxm { + struct nouveau_subdev base; + u32 action; + u8 *mxms; +}; + +static inline struct nouveau_mxm * +nouveau_mxm(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MXM]; +} + +#define nouveau_mxm_create(p,e,o,d) \ + nouveau_mxm_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_mxm_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_mxm_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) +int nouveau_mxm_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +void nouveau_mxm_destroy(struct nouveau_mxm *); + +#define _nouveau_mxm_dtor _nouveau_subdev_dtor +#define _nouveau_mxm_init _nouveau_subdev_init +#define _nouveau_mxm_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nv50_mxm_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h new file mode 100644 index 00000000..c075998d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -0,0 +1,80 @@ +#ifndef __NOUVEAU_THERM_H__ +#define __NOUVEAU_THERM_H__ + +#include <core/device.h> +#include <core/subdev.h> + +enum nouveau_therm_fan_mode { + NOUVEAU_THERM_CTRL_NONE = 0, + NOUVEAU_THERM_CTRL_MANUAL = 1, + NOUVEAU_THERM_CTRL_AUTO = 2, +}; + +enum nouveau_therm_attr_type { + NOUVEAU_THERM_ATTR_FAN_MIN_DUTY = 0, + NOUVEAU_THERM_ATTR_FAN_MAX_DUTY = 1, + NOUVEAU_THERM_ATTR_FAN_MODE = 2, + + NOUVEAU_THERM_ATTR_THRS_FAN_BOOST = 10, + NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST = 11, + NOUVEAU_THERM_ATTR_THRS_DOWN_CLK = 12, + NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST = 13, + NOUVEAU_THERM_ATTR_THRS_CRITICAL = 14, + NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST = 15, + NOUVEAU_THERM_ATTR_THRS_SHUTDOWN = 16, + NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST = 17, +}; + +struct nouveau_therm { + struct nouveau_subdev base; + + int (*pwm_ctrl)(struct nouveau_therm *, int line, bool); + int (*pwm_get)(struct nouveau_therm *, int line, u32 *, u32 *); + int (*pwm_set)(struct nouveau_therm *, int line, u32, u32); + int (*pwm_clock)(struct nouveau_therm *); + + int (*fan_get)(struct nouveau_therm *); + int (*fan_set)(struct nouveau_therm *, int); + int (*fan_sense)(struct nouveau_therm *); + + int (*temp_get)(struct nouveau_therm *); + + int (*attr_get)(struct nouveau_therm *, enum nouveau_therm_attr_type); + int (*attr_set)(struct nouveau_therm *, + enum nouveau_therm_attr_type, int); +}; + +static inline struct nouveau_therm * +nouveau_therm(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_THERM]; +} + +#define nouveau_therm_create(p,e,o,d) \ + nouveau_therm_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_therm_destroy(p) ({ \ + struct nouveau_therm *therm = (p); \ + _nouveau_therm_dtor(nv_object(therm)); \ +}) +#define nouveau_therm_init(p) ({ \ + struct nouveau_therm *therm = (p); \ + _nouveau_therm_init(nv_object(therm)); \ +}) +#define nouveau_therm_fini(p,s) ({ \ + struct nouveau_therm *therm = (p); \ + _nouveau_therm_init(nv_object(therm), (s)); \ +}) + +int nouveau_therm_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +void _nouveau_therm_dtor(struct nouveau_object *); +int _nouveau_therm_init(struct nouveau_object *); +int _nouveau_therm_fini(struct nouveau_object *, bool); + +extern struct nouveau_oclass nv40_therm_oclass; +extern struct nouveau_oclass nv50_therm_oclass; +extern struct nouveau_oclass nv84_therm_oclass; +extern struct nouveau_oclass nva3_therm_oclass; +extern struct nouveau_oclass nvd0_therm_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h new file mode 100644 index 00000000..e465d158 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h @@ -0,0 +1,61 @@ +#ifndef __NOUVEAU_TIMER_H__ +#define __NOUVEAU_TIMER_H__ + +#include <core/subdev.h> +#include <core/device.h> + +struct nouveau_alarm { + struct list_head head; + u64 timestamp; + void (*func)(struct nouveau_alarm *); +}; + +static inline void +nouveau_alarm_init(struct nouveau_alarm *alarm, + void (*func)(struct nouveau_alarm *)) +{ + INIT_LIST_HEAD(&alarm->head); + alarm->func = func; +} + +bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data); +bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data); +bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data); +void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *); + +#define NV_WAIT_DEFAULT 2000000000ULL +#define nv_wait(o,a,m,v) \ + nouveau_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v)) +#define nv_wait_ne(o,a,m,v) \ + nouveau_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v)) +#define nv_wait_cb(o,c,d) \ + nouveau_timer_wait_cb((o), NV_WAIT_DEFAULT, (c), (d)) + +struct nouveau_timer { + struct nouveau_subdev base; + u64 (*read)(struct nouveau_timer *); + void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *); +}; + +static inline struct nouveau_timer * +nouveau_timer(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_TIMER]; +} + +#define nouveau_timer_create(p,e,o,d) \ + nouveau_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \ + sizeof(**d), (void **)d) +#define nouveau_timer_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_timer_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_timer_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +int nouveau_timer_create_(struct nouveau_object *, struct nouveau_engine *, + struct nouveau_oclass *, int size, void **); + +extern struct nouveau_oclass nv04_timer_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vga.h b/drivers/gpu/drm/nouveau/core/include/subdev/vga.h new file mode 100644 index 00000000..fee09ad8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/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/core/include/subdev/vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h new file mode 100644 index 00000000..9d595efe --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h @@ -0,0 +1,142 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#ifndef __NOUVEAU_VM_H__ +#define __NOUVEAU_VM_H__ + +#include <core/object.h> +#include <core/subdev.h> +#include <core/device.h> +#include <core/mm.h> + +struct nouveau_vm_pgt { + struct nouveau_gpuobj *obj[2]; + u32 refcount[2]; +}; + +struct nouveau_vm_pgd { + struct list_head head; + struct nouveau_gpuobj *obj; +}; + +struct nouveau_gpuobj; +struct nouveau_mem; + +struct nouveau_vma { + struct list_head head; + int refcount; + struct nouveau_vm *vm; + struct nouveau_mm_node *node; + u64 offset; + u32 access; +}; + +struct nouveau_vm { + struct nouveau_vmmgr *vmm; + struct nouveau_mm mm; + int refcount; + + struct list_head pgd_list; + atomic_t engref[64]; //NVDEV_SUBDEV_NR]; + + struct nouveau_vm_pgt *pgt; + u32 fpde; + u32 lpde; +}; + +struct nouveau_vmmgr { + struct nouveau_subdev base; + + u64 limit; + u8 dma_bits; + u32 pgt_bits; + u8 spg_shift; + u8 lpg_shift; + + int (*create)(struct nouveau_vmmgr *, u64 offset, u64 length, + u64 mm_offset, struct nouveau_vm **); + + void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde, + struct nouveau_gpuobj *pgt[2]); + void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *, + struct nouveau_mem *, u32 pte, u32 cnt, + u64 phys, u64 delta); + void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *, + struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); + void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt); + void (*flush)(struct nouveau_vm *); +}; + +static inline struct nouveau_vmmgr * +nouveau_vmmgr(void *obj) +{ + return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VM]; +} + +#define nouveau_vmmgr_create(p,e,o,i,f,d) \ + nouveau_subdev_create((p), (e), (o), 0, (i), (f), (d)) +#define nouveau_vmmgr_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_vmmgr_init(p) \ + nouveau_subdev_init(&(p)->base) +#define nouveau_vmmgr_fini(p,s) \ + nouveau_subdev_fini(&(p)->base, (s)) + +#define _nouveau_vmmgr_dtor _nouveau_subdev_dtor +#define _nouveau_vmmgr_init _nouveau_subdev_init +#define _nouveau_vmmgr_fini _nouveau_subdev_fini + +extern struct nouveau_oclass nv04_vmmgr_oclass; +extern struct nouveau_oclass nv41_vmmgr_oclass; +extern struct nouveau_oclass nv44_vmmgr_oclass; +extern struct nouveau_oclass nv50_vmmgr_oclass; +extern struct nouveau_oclass nvc0_vmmgr_oclass; + +int nv04_vm_create(struct nouveau_vmmgr *, u64, u64, u64, + struct nouveau_vm **); +void nv04_vmmgr_dtor(struct nouveau_object *); + +void nv50_vm_flush_engine(struct nouveau_subdev *, int engine); +void nvc0_vm_flush_engine(struct nouveau_subdev *, u64 addr, int type); + +/* nouveau_vm.c */ +int nouveau_vm_create(struct nouveau_vmmgr *, u64 offset, u64 length, + u64 mm_offset, u32 block, struct nouveau_vm **); +int nouveau_vm_new(struct nouveau_device *, u64 offset, u64 length, + u64 mm_offset, struct nouveau_vm **); +int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **, + struct nouveau_gpuobj *pgd); +int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift, + u32 access, struct nouveau_vma *); +void nouveau_vm_put(struct nouveau_vma *); +void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *); +void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *); +void nouveau_vm_unmap(struct nouveau_vma *); +void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length); +void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length, + struct nouveau_mem *); +void nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length, + struct nouveau_mem *mem); + +#endif |
