diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_drv.h')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 219 |
1 files changed, 179 insertions, 40 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d20b9ba4b1c1..0e409414f44d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: MIT */ #ifndef __NOUVEAU_DRV_H__ #define __NOUVEAU_DRV_H__ @@ -7,10 +7,9 @@ #define DRIVER_NAME "nouveau" #define DRIVER_DESC "nVidia Riva/TNT/GeForce/Quadro/Tesla/Tegra K1+" -#define DRIVER_DATE "20120801" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 +#define DRIVER_MINOR 4 #define DRIVER_PATCHLEVEL 1 /* @@ -36,6 +35,8 @@ * programs that get directly linked with NVKM. * 1.3.1: * - implemented limited ABI16/NVIF interop + * 1.4.1: + * - add variable page sizes and compression for Turing+ */ #include <linux/notifier.h> @@ -46,25 +47,27 @@ #include <nvif/mmu.h> #include <nvif/vmm.h> -#include <drm/drmP.h> +#include <drm/drm_connector.h> +#include <drm/drm_device.h> +#include <drm/drm_drv.h> +#include <drm/drm_file.h> +#include <drm/drm_print.h> -#include <drm/ttm/ttm_bo_api.h> -#include <drm/ttm/ttm_bo_driver.h> +#include <drm/ttm/ttm_bo.h> #include <drm/ttm/ttm_placement.h> -#include <drm/ttm/ttm_memory.h> -#include <drm/ttm/ttm_module.h> -#include <drm/ttm/ttm_page_alloc.h> + +#include <drm/drm_audio_component.h> #include "uapi/drm/nouveau_drm.h" struct nouveau_channel; struct platform_device; -#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - #include "nouveau_fence.h" #include "nouveau_bios.h" +#include "nouveau_sched.h" #include "nouveau_vmm.h" +#include "nouveau_uvmm.h" struct nouveau_drm_tile { struct nouveau_fence *fence; @@ -78,11 +81,6 @@ enum nouveau_drm_object_route { NVDRM_OBJECT_ANY = NVIF_IOCTL_V0_OWNER_ANY, }; -enum nouveau_drm_notify_route { - NVDRM_NOTIFY_NVIF = 0, - NVDRM_NOTIFY_USIF -}; - enum nouveau_drm_handle { NVDRM_CHAN = 0xcccc0000, /* |= client chid */ NVDRM_NVSW = 0x55550000, @@ -96,12 +94,19 @@ struct nouveau_cli { struct nvif_device device; struct nvif_mmu mmu; struct nouveau_vmm vmm; + struct nouveau_vmm svm; + struct { + struct nouveau_uvmm *ptr; + bool disabled; + } uvmm; + + struct nouveau_sched *sched; + const struct nvif_mclass *mem; struct list_head head; void *abi16; struct list_head objects; - struct list_head notifys; char name[32]; struct work_struct work; @@ -118,6 +123,56 @@ struct nouveau_cli_work { struct dma_fence_cb cb; }; +static inline struct nouveau_uvmm * +nouveau_cli_uvmm(struct nouveau_cli *cli) +{ + return cli ? cli->uvmm.ptr : NULL; +} + +static inline struct nouveau_uvmm * +nouveau_cli_uvmm_locked(struct nouveau_cli *cli) +{ + struct nouveau_uvmm *uvmm; + + mutex_lock(&cli->mutex); + uvmm = nouveau_cli_uvmm(cli); + mutex_unlock(&cli->mutex); + + return uvmm; +} + +static inline struct nouveau_vmm * +nouveau_cli_vmm(struct nouveau_cli *cli) +{ + struct nouveau_uvmm *uvmm; + + uvmm = nouveau_cli_uvmm(cli); + if (uvmm) + return &uvmm->vmm; + + if (cli->svm.cli) + return &cli->svm; + + return &cli->vmm; +} + +static inline void +__nouveau_cli_disable_uvmm_noinit(struct nouveau_cli *cli) +{ + struct nouveau_uvmm *uvmm = nouveau_cli_uvmm(cli); + + if (!uvmm) + cli->uvmm.disabled = true; +} + +static inline void +nouveau_cli_disable_uvmm_noinit(struct nouveau_cli *cli) +{ + mutex_lock(&cli->mutex); + __nouveau_cli_disable_uvmm_noinit(cli); + mutex_unlock(&cli->mutex); +} + void nouveau_cli_work_queue(struct nouveau_cli *, struct dma_fence *, struct nouveau_cli_work *); @@ -127,16 +182,46 @@ nouveau_cli(struct drm_file *fpriv) return fpriv ? fpriv->driver_priv : NULL; } +static inline void +u_free(void *addr) +{ + kvfree(addr); +} + +static inline void * +u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size) +{ + void __user *userptr = u64_to_user_ptr(user); + size_t bytes; + + if (unlikely(check_mul_overflow(nmemb, size, &bytes))) + return ERR_PTR(-EOVERFLOW); + return vmemdup_user(userptr, bytes); +} + #include <nvif/object.h> -#include <nvif/device.h> +#include <nvif/parent.h> struct nouveau_drm { - struct nouveau_cli master; + struct nvkm_device *nvkm; + struct nvif_parent parent; + struct mutex client_mutex; + struct nvif_client _client; + struct nvif_device device; + struct nvif_mmu mmu; + struct nouveau_cli client; struct drm_device *dev; struct list_head clients; + /** + * @clients_lock: Protects access to the @clients list of &struct nouveau_cli. + */ + struct mutex clients_lock; + + u8 old_pm_cap; + struct { struct agp_bridge_data *bridge; u32 base; @@ -146,17 +231,19 @@ struct nouveau_drm { /* TTM interface support */ struct { - struct ttm_bo_device bdev; + struct ttm_device bdev; atomic_t validate_sequence; int (*move)(struct nouveau_channel *, struct ttm_buffer_object *, - struct ttm_mem_reg *, struct ttm_mem_reg *); + struct ttm_resource *, struct ttm_resource *); struct nouveau_channel *chan; struct nvif_object copy; int mtrr; int type_vram; int type_host[2]; int type_ncoh[2]; + struct mutex io_reserve_mutex; + struct list_head io_reserve_lru; } ttm; /* GEM interface support */ @@ -169,19 +256,23 @@ struct nouveau_drm { void *fence; /* Global channel management. */ + int chan_total; /* Number of channels across all runlists. */ + int chan_nr; /* 0 if per-runlist CHIDs. */ + int runl_nr; struct { - int nr; + int chan_nr; + int chan_id_base; u64 context_base; - } chan; + } *runl; + + /* Workqueue used for channel schedulers. */ + struct workqueue_struct *sched_wq; /* context for accelerated drm-internal operations */ struct nouveau_channel *cechan; struct nouveau_channel *channel; struct nvkm_gpuobj *notify; - struct nouveau_fbdev *fbcon; - struct nvif_object nvsw; struct nvif_object ntfy; - struct nvif_notify flip; /* nv10-nv40 tiling regions */ struct { @@ -192,9 +283,10 @@ struct nouveau_drm { /* modesetting */ struct nvbios vbios; struct nouveau_display *display; + bool headless; struct work_struct hpd_work; - struct work_struct fbcon_work; - int fbcon_new_state; + spinlock_t hpd_lock; + u32 hpd_pending; #ifdef CONFIG_ACPI struct notifier_block acpi_nb; #endif @@ -206,10 +298,17 @@ struct nouveau_drm { /* led management */ struct nouveau_led *led; - /* display power reference */ - bool have_disp_power_ref; - struct dev_pm_domain vga_pm_domain; + + struct nouveau_svm *svm; + + struct nouveau_dmem *dmem; + + struct { + struct drm_audio_component *component; + struct mutex lock; + bool component_registered; + } audio; }; static inline struct nouveau_drm * @@ -234,25 +333,28 @@ bool nouveau_pmops_runtime(void); struct drm_device * nouveau_platform_device_create(const struct nvkm_device_tegra_func *, struct platform_device *, struct nvkm_device **); -void nouveau_drm_device_remove(struct drm_device *dev); +void nouveau_drm_device_remove(struct nouveau_drm *); #define NV_PRINTK(l,c,f,a...) do { \ struct nouveau_cli *_cli = (c); \ dev_##l(_cli->drm->dev->dev, "%s: "f, _cli->name, ##a); \ } while(0) -#define NV_FATAL(drm,f,a...) NV_PRINTK(crit, &(drm)->client, f, ##a) -#define NV_ERROR(drm,f,a...) NV_PRINTK(err, &(drm)->client, f, ##a) -#define NV_WARN(drm,f,a...) NV_PRINTK(warn, &(drm)->client, f, ##a) -#define NV_INFO(drm,f,a...) NV_PRINTK(info, &(drm)->client, f, ##a) +#define NV_PRINTK_(l,drm,f,a...) do { \ + dev_##l((drm)->nvkm->dev, "drm: "f, ##a); \ +} while(0) +#define NV_FATAL(drm,f,a...) NV_PRINTK_(crit, (drm), f, ##a) +#define NV_ERROR(drm,f,a...) NV_PRINTK_(err, (drm), f, ##a) +#define NV_WARN(drm,f,a...) NV_PRINTK_(warn, (drm), f, ##a) +#define NV_INFO(drm,f,a...) NV_PRINTK_(info, (drm), f, ##a) #define NV_DEBUG(drm,f,a...) do { \ - if (unlikely(drm_debug & DRM_UT_DRIVER)) \ - NV_PRINTK(info, &(drm)->client, f, ##a); \ + if (drm_debug_enabled(DRM_UT_DRIVER)) \ + NV_PRINTK_(info, (drm), f, ##a); \ } while(0) #define NV_ATOMIC(drm,f,a...) do { \ - if (unlikely(drm_debug & DRM_UT_ATOMIC)) \ - NV_PRINTK(info, &(drm)->client, f, ##a); \ + if (drm_debug_enabled(DRM_UT_ATOMIC)) \ + NV_PRINTK_(info, (drm), f, ##a); \ } while(0) #define NV_PRINTK_ONCE(l,c,f,a...) NV_PRINTK(l##_once,c,f, ##a) @@ -263,4 +365,41 @@ void nouveau_drm_device_remove(struct drm_device *dev); extern int nouveau_modeset; +/*XXX: Don't use these in new code. + * + * These accessors are used in a few places (mostly older code paths) + * to get direct access to NVKM structures, where a more well-defined + * interface doesn't exist. Outside of the current use, these should + * not be relied on, and instead be implemented as NVIF. + * + * This is especially important when considering GSP-RM, as a lot the + * modules don't exist, or are "stub" implementations that just allow + * the GSP-RM paths to be bootstrapped. + */ +#include <subdev/bios.h> +#include <subdev/fb.h> +#include <subdev/gpio.h> +#include <subdev/clk.h> +#include <subdev/i2c.h> +#include <subdev/timer.h> +#include <subdev/therm.h> + +static inline struct nvkm_device * +nvxx_device(struct nouveau_drm *drm) +{ + return drm->nvkm; +} + +#define nvxx_bios(a) nvxx_device(a)->bios +#define nvxx_fb(a) nvxx_device(a)->fb +#define nvxx_gpio(a) nvxx_device(a)->gpio +#define nvxx_clk(a) nvxx_device(a)->clk +#define nvxx_i2c(a) nvxx_device(a)->i2c +#define nvxx_iccsense(a) nvxx_device(a)->iccsense +#define nvxx_therm(a) nvxx_device(a)->therm +#define nvxx_volt(a) nvxx_device(a)->volt + +#include <engine/gr.h> + +#define nvxx_gr(a) nvxx_device(a)->gr #endif |
