From 0567776b698bb2eec92ab55e603c5af07d0a51d0 Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Tue, 10 Mar 2020 16:31:15 +0300 Subject: drm/nouveau: make nouveau_drm_debugfs_init() return 0 Since 987d65d01356 (drm: debugfs: make drm_debugfs_create_files() never fail), there is no need to ever check for the the return value of debugfs_create_file() and drm_debugfs_create_files(). Therefore, remove unnecessary checks and error handling in nouveau_drm_debugfs_init() and have the function return 0 directly. v2: have nouveau_drm_debugfs_init() return 0 instead of void so as not to introduce any build warnings to enable individual patch compilation. References: https://lists.freedesktop.org/archives/dri-devel/2020-February/257183.html Signed-off-by: Wambui Karuga Reviewed-by: Greg Kroah-Hartman Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200310133121.27913-12-wambui.karugax@gmail.com --- drivers/gpu/drm/nouveau/nouveau_debugfs.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 7dfbbbc1beea..15a3d40edf02 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -222,22 +222,18 @@ nouveau_drm_debugfs_init(struct drm_minor *minor) { struct nouveau_drm *drm = nouveau_drm(minor->dev); struct dentry *dentry; - int i, ret; + int i; for (i = 0; i < ARRAY_SIZE(nouveau_debugfs_files); i++) { - dentry = debugfs_create_file(nouveau_debugfs_files[i].name, - S_IRUGO | S_IWUSR, - minor->debugfs_root, minor->dev, - nouveau_debugfs_files[i].fops); - if (!dentry) - return -ENOMEM; + debugfs_create_file(nouveau_debugfs_files[i].name, + S_IRUGO | S_IWUSR, + minor->debugfs_root, minor->dev, + nouveau_debugfs_files[i].fops); } - ret = drm_debugfs_create_files(nouveau_debugfs_list, - NOUVEAU_DEBUGFS_ENTRIES, - minor->debugfs_root, minor); - if (ret) - return ret; + drm_debugfs_create_files(nouveau_debugfs_list, + NOUVEAU_DEBUGFS_ENTRIES, + minor->debugfs_root, minor); /* Set the size of the vbios since we know it, and it's confusing to * userspace if it wants to seek() but the file has a length of 0 -- cgit v1.2.3 From 7ce84471e3c72e23020b046714358b45a7ffe9ab Mon Sep 17 00:00:00 2001 From: Wambui Karuga Date: Tue, 10 Mar 2020 16:31:21 +0300 Subject: drm: convert .debugfs_init() hook to return void. As a result of commit 987d65d01356 (drm: debugfs: make drm_debugfs_create_files() never fail) and changes to various debugfs functions in drm/core and across various drivers, there is no need for the drm_driver.debugfs_init() hook to have a return value. Therefore, declare it as void. This also includes refactoring all users of the .debugfs_init() hook to return void across the subsystem. v2: include changes to the hook and drivers that use it in one patch to prevent driver breakage and enable individual successful compilation of this change. References: https://lists.freedesktop.org/archives/dri-devel/2020-February/257183.html Signed-off-by: Wambui Karuga Reviewed-by: Greg Kroah-Hartman Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200310133121.27913-18-wambui.karugax@gmail.com --- drivers/gpu/drm/arc/arcpgu_drv.c | 3 +-- drivers/gpu/drm/arm/hdlcd_drv.c | 3 +-- drivers/gpu/drm/arm/malidp_drv.c | 3 +-- drivers/gpu/drm/drm_atomic.c | 3 +-- drivers/gpu/drm/drm_client.c | 4 +--- drivers/gpu/drm/drm_crtc_internal.h | 2 +- drivers/gpu/drm/drm_debugfs.c | 12 +++--------- drivers/gpu/drm/drm_framebuffer.c | 4 +--- drivers/gpu/drm/drm_gem_vram_helper.c | 6 +----- drivers/gpu/drm/drm_internal.h | 2 +- drivers/gpu/drm/drm_mipi_dbi.c | 6 +----- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 4 +--- drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 6 ++---- drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 2 +- drivers/gpu/drm/msm/msm_debugfs.c | 12 +++--------- drivers/gpu/drm/msm/msm_debugfs.h | 2 +- drivers/gpu/drm/msm/msm_gpu.h | 2 +- drivers/gpu/drm/nouveau/nouveau_debugfs.c | 6 ++---- drivers/gpu/drm/nouveau/nouveau_debugfs.h | 8 +++----- drivers/gpu/drm/omapdrm/omap_debugfs.c | 4 +--- drivers/gpu/drm/omapdrm/omap_drv.h | 2 +- drivers/gpu/drm/pl111/pl111_debugfs.c | 4 +--- drivers/gpu/drm/pl111/pl111_drm.h | 2 +- drivers/gpu/drm/qxl/qxl_debugfs.c | 21 +++++++-------------- drivers/gpu/drm/qxl/qxl_drv.h | 13 +++++-------- drivers/gpu/drm/qxl/qxl_ttm.c | 6 ++---- drivers/gpu/drm/sti/sti_drv.c | 3 +-- drivers/gpu/drm/tegra/drm.c | 3 +-- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 +--- drivers/gpu/drm/v3d/v3d_debugfs.c | 3 +-- drivers/gpu/drm/v3d/v3d_drv.h | 2 +- drivers/gpu/drm/vc4/vc4_debugfs.c | 4 +--- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 3 +-- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 +- include/drm/drm_client.h | 2 +- include/drm/drm_drv.h | 2 +- include/drm/drm_gem_vram_helper.h | 2 +- include/drm/drm_mipi_dbi.h | 2 +- 39 files changed, 58 insertions(+), 118 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 660b25f9588e..c05d001163e0 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -137,12 +137,11 @@ static struct drm_info_list arcpgu_debugfs_list[] = { { "clocks", arcpgu_show_pxlclock, 0 }, }; -static int arcpgu_debugfs_init(struct drm_minor *minor) +static void arcpgu_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(arcpgu_debugfs_list, ARRAY_SIZE(arcpgu_debugfs_list), minor->debugfs_root, minor); - return 0; } #endif diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index bd0ad6f46a97..194419f47c5e 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -224,12 +224,11 @@ static struct drm_info_list hdlcd_debugfs_list[] = { { "clocks", hdlcd_show_pxlclock, 0 }, }; -static int hdlcd_debugfs_init(struct drm_minor *minor) +static void hdlcd_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(hdlcd_debugfs_list, ARRAY_SIZE(hdlcd_debugfs_list), minor->debugfs_root, minor); - return 0; } #endif diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index 37d92a06318e..def8c9ffafca 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c @@ -548,7 +548,7 @@ static const struct file_operations malidp_debugfs_fops = { .release = single_release, }; -static int malidp_debugfs_init(struct drm_minor *minor) +static void malidp_debugfs_init(struct drm_minor *minor) { struct malidp_drm *malidp = minor->dev->dev_private; @@ -557,7 +557,6 @@ static int malidp_debugfs_init(struct drm_minor *minor) spin_lock_init(&malidp->errors_lock); debugfs_create_file("debug", S_IRUGO | S_IWUSR, minor->debugfs_root, minor->dev, &malidp_debugfs_fops); - return 0; } #endif //CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index c0056d9cc139..965173fd0ac2 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1641,11 +1641,10 @@ static const struct drm_info_list drm_atomic_debugfs_list[] = { {"state", drm_state_info, 0}, }; -int drm_atomic_debugfs_init(struct drm_minor *minor) +void drm_atomic_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(drm_atomic_debugfs_list, ARRAY_SIZE(drm_atomic_debugfs_list), minor->debugfs_root, minor); - return 0; } #endif diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 82fbdee407b2..8cb93f5209a4 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -457,12 +457,10 @@ static const struct drm_info_list drm_client_debugfs_list[] = { { "internal_clients", drm_client_debugfs_internal_clients, 0 }, }; -int drm_client_debugfs_init(struct drm_minor *minor) +void drm_client_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(drm_client_debugfs_list, ARRAY_SIZE(drm_client_debugfs_list), minor->debugfs_root, minor); - - return 0; } #endif diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index d2d43e0b060b..da96b2f64d7e 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -225,7 +225,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, /* drm_atomic.c */ #ifdef CONFIG_DEBUG_FS struct drm_minor; -int drm_atomic_debugfs_init(struct drm_minor *minor); +void drm_atomic_debugfs_init(struct drm_minor *minor); #endif int __drm_atomic_helper_disable_plane(struct drm_plane *plane, diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index e13f21642f88..2bea22130703 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -207,7 +207,6 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, { struct drm_device *dev = minor->dev; char name[64]; - int ret; INIT_LIST_HEAD(&minor->debugfs_list); mutex_init(&minor->debugfs_lock); @@ -227,14 +226,9 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, drm_client_debugfs_init(minor); } - if (dev->driver->debugfs_init) { - ret = dev->driver->debugfs_init(minor); - if (ret) { - DRM_ERROR("DRM: Driver failed to initialize " - "/sys/kernel/debug/dri.\n"); - return ret; - } - } + if (dev->driver->debugfs_init) + dev->driver->debugfs_init(minor); + return 0; } diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 46be88271fe5..0375b3d7f8d0 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -1207,12 +1207,10 @@ static const struct drm_info_list drm_framebuffer_debugfs_list[] = { { "framebuffer", drm_framebuffer_info, 0 }, }; -int drm_framebuffer_debugfs_init(struct drm_minor *minor) +void drm_framebuffer_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(drm_framebuffer_debugfs_list, ARRAY_SIZE(drm_framebuffer_debugfs_list), minor->debugfs_root, minor); - - return 0; } #endif diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index c8bcc8609650..76506bedac11 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -1042,18 +1042,14 @@ static const struct drm_info_list drm_vram_mm_debugfs_list[] = { * * @minor: drm minor device. * - * Returns: - * 0 on success, or - * a negative error code otherwise. */ -int drm_vram_mm_debugfs_init(struct drm_minor *minor) +void drm_vram_mm_debugfs_init(struct drm_minor *minor) { #if defined(CONFIG_DEBUG_FS) drm_debugfs_create_files(drm_vram_mm_debugfs_list, ARRAY_SIZE(drm_vram_mm_debugfs_list), minor->debugfs_root, minor); #endif - return 0; } EXPORT_SYMBOL(drm_vram_mm_debugfs_init); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 5714a78365ac..8b9e8bbca9b1 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -235,4 +235,4 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, /* drm_framebuffer.c */ void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent, const struct drm_framebuffer *fb); -int drm_framebuffer_debugfs_init(struct drm_minor *minor); +void drm_framebuffer_debugfs_init(struct drm_minor *minor); diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 558baf989f5a..113a767442d3 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -1308,10 +1308,8 @@ static const struct file_operations mipi_dbi_debugfs_command_fops = { * controller or getting the read command values. * Drivers can use this as their &drm_driver->debugfs_init callback. * - * Returns: - * Zero on success, negative error code on failure. */ -int mipi_dbi_debugfs_init(struct drm_minor *minor) +void mipi_dbi_debugfs_init(struct drm_minor *minor) { struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(minor->dev); umode_t mode = S_IFREG | S_IWUSR; @@ -1320,8 +1318,6 @@ int mipi_dbi_debugfs_init(struct drm_minor *minor) mode |= S_IRUGO; debugfs_create_file("command", mode, minor->debugfs_root, dbidev, &mipi_dbi_debugfs_command_fops); - - return 0; } EXPORT_SYMBOL(mipi_dbi_debugfs_init); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index a65d30a48a9d..a39735316ca5 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -231,13 +231,11 @@ static struct drm_info_list etnaviv_debugfs_list[] = { {"ring", show_each_gpu, 0, etnaviv_ring_show}, }; -static int etnaviv_debugfs_init(struct drm_minor *minor) +static void etnaviv_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(etnaviv_debugfs_list, ARRAY_SIZE(etnaviv_debugfs_list), minor->debugfs_root, minor); - - return 0; } #endif diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c index 011ab6353dbb..8cae2ca4af6b 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c @@ -148,12 +148,12 @@ reset_set(void *data, u64 val) DEFINE_SIMPLE_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n"); -int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor) +void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor) { struct drm_device *dev; if (!minor) - return 0; + return; dev = minor->dev; @@ -163,6 +163,4 @@ int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor) debugfs_create_file("reset", S_IWUGO, minor->debugfs_root, dev, &reset_fops); - - return 0; } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h index 833468ce6b6d..54868d4e3958 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -41,7 +41,7 @@ struct a5xx_gpu { #define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base) #ifdef CONFIG_DEBUG_FS -int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor); +void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor); #endif /* diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 6378157e1fff..ee2e270f464c 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -214,11 +214,10 @@ int msm_debugfs_late_init(struct drm_device *dev) return ret; } -int msm_debugfs_init(struct drm_minor *minor) +void msm_debugfs_init(struct drm_minor *minor) { struct drm_device *dev = minor->dev; struct msm_drm_private *priv = dev->dev_private; - int ret; drm_debugfs_create_files(msm_debugfs_list, ARRAY_SIZE(msm_debugfs_list), @@ -227,13 +226,8 @@ int msm_debugfs_init(struct drm_minor *minor) debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, dev, &msm_gpu_fops); - if (priv->kms && priv->kms->funcs->debugfs_init) { - ret = priv->kms->funcs->debugfs_init(priv->kms, minor); - if (ret) - return ret; - } - - return 0; + if (priv->kms && priv->kms->funcs->debugfs_init) + priv->kms->funcs->debugfs_init(priv->kms, minor); } #endif diff --git a/drivers/gpu/drm/msm/msm_debugfs.h b/drivers/gpu/drm/msm/msm_debugfs.h index 2b91f8c178ad..ef58f66abbb3 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.h +++ b/drivers/gpu/drm/msm/msm_debugfs.h @@ -8,7 +8,7 @@ #define __MSM_DEBUGFS_H__ #ifdef CONFIG_DEBUG_FS -int msm_debugfs_init(struct drm_minor *minor); +void msm_debugfs_init(struct drm_minor *minor); #endif #endif /* __MSM_DEBUGFS_H__ */ diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index be5bc2e8425c..6ccae4ba905c 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -57,7 +57,7 @@ struct msm_gpu_funcs { void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state, struct drm_printer *p); /* for generation specific debugfs: */ - int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); + void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); #endif unsigned long (*gpu_busy)(struct msm_gpu *gpu); struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu); diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 15a3d40edf02..63cb5e432f8a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -217,7 +217,7 @@ static const struct nouveau_debugfs_files { {"pstate", &nouveau_pstate_fops}, }; -int +void nouveau_drm_debugfs_init(struct drm_minor *minor) { struct nouveau_drm *drm = nouveau_drm(minor->dev); @@ -240,12 +240,10 @@ nouveau_drm_debugfs_init(struct drm_minor *minor) */ dentry = debugfs_lookup("vbios.rom", minor->debugfs_root); if (!dentry) - return 0; + return; d_inode(dentry)->i_size = drm->vbios.length; dput(dentry); - - return 0; } int diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.h b/drivers/gpu/drm/nouveau/nouveau_debugfs.h index 8909c010e8ea..77f0323b38ba 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.h +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.h @@ -18,15 +18,13 @@ nouveau_debugfs(struct drm_device *dev) return nouveau_drm(dev)->debugfs; } -extern int nouveau_drm_debugfs_init(struct drm_minor *); +extern void nouveau_drm_debugfs_init(struct drm_minor *); extern int nouveau_debugfs_init(struct nouveau_drm *); extern void nouveau_debugfs_fini(struct nouveau_drm *); #else -static inline int +static inline void nouveau_drm_debugfs_init(struct drm_minor *minor) -{ - return 0; -} +{} static inline int nouveau_debugfs_init(struct nouveau_drm *drm) diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c index ed63dcced79a..b57fbe8a0ac2 100644 --- a/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c @@ -80,7 +80,7 @@ static struct drm_info_list omap_dmm_debugfs_list[] = { {"tiler_map", tiler_map_show, 0}, }; -int omap_debugfs_init(struct drm_minor *minor) +void omap_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(omap_debugfs_list, ARRAY_SIZE(omap_debugfs_list), @@ -90,8 +90,6 @@ int omap_debugfs_init(struct drm_minor *minor) drm_debugfs_create_files(omap_dmm_debugfs_list, ARRAY_SIZE(omap_dmm_debugfs_list), minor->debugfs_root, minor); - - return 0; } #endif diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 7c4b66efcaa7..8a1fac680138 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -82,6 +82,6 @@ struct omap_drm_private { }; -int omap_debugfs_init(struct drm_minor *minor); +void omap_debugfs_init(struct drm_minor *minor); #endif /* __OMAPDRM_DRV_H__ */ diff --git a/drivers/gpu/drm/pl111/pl111_debugfs.c b/drivers/gpu/drm/pl111/pl111_debugfs.c index 5595b19c91ce..26ca8cdf3e60 100644 --- a/drivers/gpu/drm/pl111/pl111_debugfs.c +++ b/drivers/gpu/drm/pl111/pl111_debugfs.c @@ -51,12 +51,10 @@ static const struct drm_info_list pl111_debugfs_list[] = { {"regs", pl111_debugfs_regs, 0}, }; -int +void pl111_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(pl111_debugfs_list, ARRAY_SIZE(pl111_debugfs_list), minor->debugfs_root, minor); - - return 0; } diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h index 77d2da9a8a7c..ba399bcb792f 100644 --- a/drivers/gpu/drm/pl111/pl111_drm.h +++ b/drivers/gpu/drm/pl111/pl111_drm.h @@ -84,6 +84,6 @@ struct pl111_drm_dev_private { int pl111_display_init(struct drm_device *dev); irqreturn_t pl111_irq(int irq, void *data); -int pl111_debugfs_init(struct drm_minor *minor); +void pl111_debugfs_init(struct drm_minor *minor); #endif /* _PL111_DRM_H_ */ diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index a4f4175bbdbe..88123047fdd4 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c @@ -79,36 +79,30 @@ static struct drm_info_list qxl_debugfs_list[] = { #define QXL_DEBUGFS_ENTRIES ARRAY_SIZE(qxl_debugfs_list) #endif -int +void qxl_debugfs_init(struct drm_minor *minor) { #if defined(CONFIG_DEBUG_FS) - int r; struct qxl_device *dev = (struct qxl_device *) minor->dev->dev_private; drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, minor->debugfs_root, minor); - r = qxl_ttm_debugfs_init(dev); - if (r) { - DRM_ERROR("Failed to init TTM debugfs\n"); - return r; - } + qxl_ttm_debugfs_init(dev); #endif - return 0; } -int qxl_debugfs_add_files(struct qxl_device *qdev, - struct drm_info_list *files, - unsigned int nfiles) +void qxl_debugfs_add_files(struct qxl_device *qdev, + struct drm_info_list *files, + unsigned int nfiles) { unsigned int i; for (i = 0; i < qdev->debugfs_count; i++) { if (qdev->debugfs[i].files == files) { /* Already registered */ - return 0; + return; } } @@ -116,7 +110,7 @@ int qxl_debugfs_add_files(struct qxl_device *qdev, if (i > QXL_DEBUGFS_MAX_COMPONENTS) { DRM_ERROR("Reached maximum number of debugfs components.\n"); DRM_ERROR("Report so we increase QXL_DEBUGFS_MAX_COMPONENTS.\n"); - return -EINVAL; + return; } qdev->debugfs[qdev->debugfs_count].files = files; qdev->debugfs[qdev->debugfs_count].num_files = nfiles; @@ -126,5 +120,4 @@ int qxl_debugfs_add_files(struct qxl_device *qdev, qdev->ddev.primary->debugfs_root, qdev->ddev.primary); #endif - return 0; } diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 27e45a2d6b52..435126facc9b 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -190,9 +190,6 @@ struct qxl_debugfs { unsigned int num_files; }; -int qxl_debugfs_add_files(struct qxl_device *rdev, - struct drm_info_list *files, - unsigned int nfiles); int qxl_debugfs_fence_init(struct qxl_device *rdev); struct qxl_device; @@ -442,8 +439,8 @@ int qxl_garbage_collect(struct qxl_device *qdev); /* debugfs */ -int qxl_debugfs_init(struct drm_minor *minor); -int qxl_ttm_debugfs_init(struct qxl_device *qdev); +void qxl_debugfs_init(struct drm_minor *minor); +void qxl_ttm_debugfs_init(struct qxl_device *qdev); /* qxl_prime.c */ int qxl_gem_prime_pin(struct drm_gem_object *obj); @@ -461,9 +458,9 @@ int qxl_gem_prime_mmap(struct drm_gem_object *obj, int qxl_irq_init(struct qxl_device *qdev); irqreturn_t qxl_irq_handler(int irq, void *arg); -int qxl_debugfs_add_files(struct qxl_device *qdev, - struct drm_info_list *files, - unsigned int nfiles); +void qxl_debugfs_add_files(struct qxl_device *qdev, + struct drm_info_list *files, + unsigned int nfiles); int qxl_surface_id_alloc(struct qxl_device *qdev, struct qxl_bo *surf); diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 62a5e424971b..93a2eb14844b 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -322,7 +322,7 @@ static int qxl_mm_dump_table(struct seq_file *m, void *data) } #endif -int qxl_ttm_debugfs_init(struct qxl_device *qdev) +void qxl_ttm_debugfs_init(struct qxl_device *qdev) { #if defined(CONFIG_DEBUG_FS) static struct drm_info_list qxl_mem_types_list[QXL_DEBUGFS_MEM_TYPES]; @@ -343,8 +343,6 @@ int qxl_ttm_debugfs_init(struct qxl_device *qdev) qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_PRIV].priv; } - return qxl_debugfs_add_files(qdev, qxl_mem_types_list, i); -#else - return 0; + qxl_debugfs_add_files(qdev, qxl_mem_types_list, i); #endif } diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index 5ab36f6001fc..3f9db3e3f397 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -92,7 +92,7 @@ static struct drm_info_list sti_drm_dbg_list[] = { {"fps_get", sti_drm_fps_dbg_show, 0}, }; -static int sti_drm_dbg_init(struct drm_minor *minor) +static void sti_drm_dbg_init(struct drm_minor *minor) { drm_debugfs_create_files(sti_drm_dbg_list, ARRAY_SIZE(sti_drm_dbg_list), @@ -102,7 +102,6 @@ static int sti_drm_dbg_init(struct drm_minor *minor) minor->dev, &sti_drm_fps_fops); DRM_INFO("%s: debugfs installed\n", DRIVER_NAME); - return 0; } static const struct drm_mode_config_funcs sti_mode_config_funcs = { diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 6ec224f3d824..d4f51b5c7ee5 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -839,12 +839,11 @@ static struct drm_info_list tegra_debugfs_list[] = { { "iova", tegra_debugfs_iova, 0 }, }; -static int tegra_debugfs_init(struct drm_minor *minor) +static void tegra_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(tegra_debugfs_list, ARRAY_SIZE(tegra_debugfs_list), minor->debugfs_root, minor); - return 0; } #endif diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 3f7071eb9c78..78c1877d13a8 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -478,7 +478,7 @@ static struct drm_info_list tilcdc_debugfs_list[] = { { "mm", tilcdc_mm_show, 0 }, }; -static int tilcdc_debugfs_init(struct drm_minor *minor) +static void tilcdc_debugfs_init(struct drm_minor *minor) { struct tilcdc_module *mod; @@ -489,8 +489,6 @@ static int tilcdc_debugfs_init(struct drm_minor *minor) list_for_each_entry(mod, &module_list, list) if (mod->funcs->debugfs_init) mod->funcs->debugfs_init(mod, minor); - - return 0; } #endif diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c index 57dded6a3957..2b0ea5f8febd 100644 --- a/drivers/gpu/drm/v3d/v3d_debugfs.c +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c @@ -258,11 +258,10 @@ static const struct drm_info_list v3d_debugfs_list[] = { {"bo_stats", v3d_debugfs_bo_stats, 0}, }; -int +void v3d_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(v3d_debugfs_list, ARRAY_SIZE(v3d_debugfs_list), minor->debugfs_root, minor); - return 0; } diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index ac2603334587..e0775c884553 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -316,7 +316,7 @@ struct drm_gem_object *v3d_prime_import_sg_table(struct drm_device *dev, struct sg_table *sgt); /* v3d_debugfs.c */ -int v3d_debugfs_init(struct drm_minor *minor); +void v3d_debugfs_init(struct drm_minor *minor); /* v3d_fence.c */ extern const struct dma_fence_ops v3d_fence_ops; diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c index 1835f12337ec..4fbbf980a299 100644 --- a/drivers/gpu/drm/vc4/vc4_debugfs.c +++ b/drivers/gpu/drm/vc4/vc4_debugfs.c @@ -20,7 +20,7 @@ struct vc4_debugfs_info_entry { * Called at drm_dev_register() time on each of the minors registered * by the DRM device, to attach the debugfs files. */ -int +void vc4_debugfs_init(struct drm_minor *minor) { struct vc4_dev *vc4 = to_vc4_dev(minor->dev); @@ -33,8 +33,6 @@ vc4_debugfs_init(struct drm_minor *minor) drm_debugfs_create_files(&entry->info, 1, minor->debugfs_root, minor); } - - return 0; } static int vc4_debugfs_regset32(struct seq_file *m, void *unused) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 139d25a8328e..3b1f02efefbe 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -759,7 +759,7 @@ void vc4_crtc_get_margins(struct drm_crtc_state *state, unsigned int *top, unsigned int *bottom); /* vc4_debugfs.c */ -int vc4_debugfs_init(struct drm_minor *minor); +void vc4_debugfs_init(struct drm_minor *minor); #ifdef CONFIG_DEBUG_FS void vc4_debugfs_add_file(struct drm_device *drm, const char *filename, diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index e27120d512b0..3221520f61f0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -72,11 +72,10 @@ static struct drm_info_list virtio_gpu_debugfs_list[] = { #define VIRTIO_GPU_DEBUGFS_ENTRIES ARRAY_SIZE(virtio_gpu_debugfs_list) -int +void virtio_gpu_debugfs_init(struct drm_minor *minor) { drm_debugfs_create_files(virtio_gpu_debugfs_list, VIRTIO_GPU_DEBUGFS_ENTRIES, minor->debugfs_root, minor); - return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index c1824bdf2418..824f9f15926c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -379,6 +379,6 @@ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( struct sg_table *sgt); /* virgl debugfs */ -int virtio_gpu_debugfs_init(struct drm_minor *minor); +void virtio_gpu_debugfs_init(struct drm_minor *minor); #endif diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 3ed5dee899fd..7402f852d3c4 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -188,6 +188,6 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); drm_for_each_connector_iter(connector, iter) \ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) -int drm_client_debugfs_init(struct drm_minor *minor); +void drm_client_debugfs_init(struct drm_minor *minor); #endif diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 97109df5beac..c6ae888c672b 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -323,7 +323,7 @@ struct drm_driver { * * Allows drivers to create driver-specific debugfs files. */ - int (*debugfs_init)(struct drm_minor *minor); + void (*debugfs_init)(struct drm_minor *minor); /** * @gem_free_object: deconstructor for drm_gem_objects diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index 0f6e47213d8d..b63bcd1b996d 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -196,7 +196,7 @@ static inline struct drm_vram_mm *drm_vram_mm_of_bdev( return container_of(bdev, struct drm_vram_mm, bdev); } -int drm_vram_mm_debugfs_init(struct drm_minor *minor); +void drm_vram_mm_debugfs_init(struct drm_minor *minor); /* * Helpers for integration with struct drm_device diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index 33f325f5af2b..30ebdfd8a51f 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -192,7 +192,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, }) #ifdef CONFIG_DEBUG_FS -int mipi_dbi_debugfs_init(struct drm_minor *minor); +void mipi_dbi_debugfs_init(struct drm_minor *minor); #else #define mipi_dbi_debugfs_init NULL #endif -- cgit v1.2.3 From 3f9becf950aa9ceb949f6df90fd3d027d30fe69c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 26 Mar 2020 22:10:03 +0100 Subject: drm/nouveau/therm: convert to use i2c_new_client_device() Move away from the deprecated API and return the shiny new ERRPTR where useful. Signed-off-by: Wolfram Sang Acked-by: Alex Deucher Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200326211005.13301-6-wsa+renesas@sang-engineering.com --- drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c index 03b355dabab3..abf3eda683f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c @@ -36,8 +36,8 @@ probe_monitoring_device(struct nvkm_i2c_bus *bus, request_module("%s%s", I2C_MODULE_PREFIX, info->type); - client = i2c_new_device(&bus->i2c, info); - if (!client) + client = i2c_new_client_device(&bus->i2c, info); + if (IS_ERR(client)) return false; if (!client->dev.driver || -- cgit v1.2.3 From bbd540c072a8f7ad7aa4ba6a67ad5b30322e188b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 29 Jan 2020 17:32:22 +1000 Subject: drm/nouveau: fix out-of-tree module build The $(srctree) addition a while back busted building the out-of-tree version of the module, and I've been hacking it up ever since. This allows us to work around the issue. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kbuild | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 7a62fa04272d..49e57fba4925 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -1,8 +1,10 @@ +NOUVEAU_PATH ?= $(srctree) + # SPDX-License-Identifier: MIT -ccflags-y += -I $(srctree)/$(src)/include -ccflags-y += -I $(srctree)/$(src)/include/nvkm -ccflags-y += -I $(srctree)/$(src)/nvkm -ccflags-y += -I $(srctree)/$(src) +ccflags-y += -I $(NOUVEAU_PATH)/$(src)/include +ccflags-y += -I $(NOUVEAU_PATH)/$(src)/include/nvkm +ccflags-y += -I $(NOUVEAU_PATH)/$(src)/nvkm +ccflags-y += -I $(NOUVEAU_PATH)/$(src) # NVKM - HW resource manager #- code also used by various userspace tools/tests -- cgit v1.2.3 From e27ad35e69f6289561d0de699c58a90e4d9200c2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 6 Feb 2020 11:19:39 +0100 Subject: drm/nouveau/kms: Remove unused fields from struct nouveau_framebuffer Signed-off-by: Thomas Zimmermann Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index de004018ab5c..178b71ffc07c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -12,11 +12,6 @@ struct nouveau_framebuffer { struct drm_framebuffer base; struct nouveau_bo *nvbo; struct nouveau_vma *vma; - u32 r_handle; - u32 r_format; - u32 r_pitch; - struct nvif_object h_base[4]; - struct nvif_object h_core; }; static inline struct nouveau_framebuffer * -- cgit v1.2.3 From 84c862b572f88dd41dfd06df63454fb1010fee05 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 6 Feb 2020 11:19:40 +0100 Subject: drm/nouveau/kms: Move struct nouveau_framebuffer.vma to struct nouveau_fbdev The vma field of struct nouveau_framebuffer is a special field for the the accelerated fbdev console. Hence there's at most one single instance for the active console. Moving it into struct nouveau_fbdev makes struct nouveau_framebuffer slightly smaller and brings it closer to struct drm_framebuffer. Signed-off-by: Thomas Zimmermann Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.h | 1 - drivers/gpu/drm/nouveau/nouveau_fbcon.c | 6 +++--- drivers/gpu/drm/nouveau/nouveau_fbcon.h | 3 +++ drivers/gpu/drm/nouveau/nv50_fbcon.c | 9 ++++----- drivers/gpu/drm/nouveau/nvc0_fbcon.c | 9 ++++----- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 178b71ffc07c..d71de95ece75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -11,7 +11,6 @@ struct nouveau_framebuffer { struct drm_framebuffer base; struct nouveau_bo *nvbo; - struct nouveau_vma *vma; }; static inline struct nouveau_framebuffer * diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 24d543a01f43..dcdabd2a1a6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -353,7 +353,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, chan = nouveau_nofbaccel ? NULL : drm->channel; if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_vma_new(nvbo, chan->vmm, &fb->vma); + ret = nouveau_vma_new(nvbo, chan->vmm, &fbcon->vma); if (ret) { NV_ERROR(drm, "failed to map fb into chan: %d\n", ret); chan = NULL; @@ -400,7 +400,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, out_unlock: if (chan) - nouveau_vma_del(&fb->vma); + nouveau_vma_del(&fbcon->vma); nouveau_bo_unmap(fb->nvbo); out_unpin: nouveau_bo_unpin(fb->nvbo); @@ -419,7 +419,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) drm_fb_helper_fini(&fbcon->helper); if (nouveau_fb && nouveau_fb->nvbo) { - nouveau_vma_del(&nouveau_fb->vma); + nouveau_vma_del(&fbcon->vma); nouveau_bo_unmap(nouveau_fb->nvbo); nouveau_bo_unpin(nouveau_fb->nvbo); drm_framebuffer_put(&nouveau_fb->base); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 73a7eeba3973..1796d8824580 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -31,6 +31,8 @@ #include "nouveau_display.h" +struct nouveau_vma; + struct nouveau_fbdev { struct drm_fb_helper helper; /* must be first */ unsigned int saved_flags; @@ -41,6 +43,7 @@ struct nouveau_fbdev { struct nvif_object gdi; struct nvif_object blit; struct nvif_object twod; + struct nouveau_vma *vma; struct mutex hotplug_lock; bool hotplug_waiting; diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index facd18564e0d..47428f79ede8 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -149,7 +149,6 @@ int nv50_fbcon_accel_init(struct fb_info *info) { struct nouveau_fbdev *nfbdev = info->par; - struct nouveau_framebuffer *fb = nouveau_framebuffer(nfbdev->helper.fb); struct drm_device *dev = nfbdev->helper.dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_channel *chan = drm->channel; @@ -240,8 +239,8 @@ nv50_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, info->fix.line_length); OUT_RING(chan, info->var.xres_virtual); OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb->vma->addr)); - OUT_RING(chan, lower_32_bits(fb->vma->addr)); + OUT_RING(chan, upper_32_bits(nfbdev->vma->addr)); + OUT_RING(chan, lower_32_bits(nfbdev->vma->addr)); BEGIN_NV04(chan, NvSub2D, 0x0230, 2); OUT_RING(chan, format); OUT_RING(chan, 1); @@ -249,8 +248,8 @@ nv50_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, info->fix.line_length); OUT_RING(chan, info->var.xres_virtual); OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb->vma->addr)); - OUT_RING(chan, lower_32_bits(fb->vma->addr)); + OUT_RING(chan, upper_32_bits(nfbdev->vma->addr)); + OUT_RING(chan, lower_32_bits(nfbdev->vma->addr)); FIRE_RING(chan); return 0; diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index c0deef4fe727..cb56163ed608 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -150,7 +150,6 @@ nvc0_fbcon_accel_init(struct fb_info *info) { struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->helper.dev; - struct nouveau_framebuffer *fb = nouveau_framebuffer(nfbdev->helper.fb); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_channel *chan = drm->channel; int ret, format; @@ -240,8 +239,8 @@ nvc0_fbcon_accel_init(struct fb_info *info) OUT_RING (chan, info->fix.line_length); OUT_RING (chan, info->var.xres_virtual); OUT_RING (chan, info->var.yres_virtual); - OUT_RING (chan, upper_32_bits(fb->vma->addr)); - OUT_RING (chan, lower_32_bits(fb->vma->addr)); + OUT_RING (chan, upper_32_bits(nfbdev->vma->addr)); + OUT_RING (chan, lower_32_bits(nfbdev->vma->addr)); BEGIN_NVC0(chan, NvSub2D, 0x0230, 10); OUT_RING (chan, format); OUT_RING (chan, 1); @@ -251,8 +250,8 @@ nvc0_fbcon_accel_init(struct fb_info *info) OUT_RING (chan, info->fix.line_length); OUT_RING (chan, info->var.xres_virtual); OUT_RING (chan, info->var.yres_virtual); - OUT_RING (chan, upper_32_bits(fb->vma->addr)); - OUT_RING (chan, lower_32_bits(fb->vma->addr)); + OUT_RING (chan, upper_32_bits(nfbdev->vma->addr)); + OUT_RING (chan, lower_32_bits(nfbdev->vma->addr)); FIRE_RING (chan); return 0; -- cgit v1.2.3 From 183405879255919c879edb37db70becfac9a4033 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 6 Feb 2020 11:19:41 +0100 Subject: drm/nouveau/kms: Remove field nvbo from struct nouveau_framebuffer The buffer object stored in nvbo is also available GEM object in obj[0] of struct drm_framebuffer. Therefore remove nvbo in favor obj[0] and replace all references accordingly. This may require an additional cast. With this change we can already replace nouveau_user_framebuffer_destroy() and nouveau_user_framebuffer_create_handle() with generic GEM helpers. Calls to nouveau_framebuffer_new() receive a GEM object. Signed-off-by: Thomas Zimmermann Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv04/crtc.c | 19 ++++++++-------- drivers/gpu/drm/nouveau/dispnv04/disp.c | 21 +++++++++--------- drivers/gpu/drm/nouveau/dispnv04/overlay.c | 21 ++++++++++-------- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 26 +++++++++++++--------- drivers/gpu/drm/nouveau/nouveau_display.c | 35 +++++------------------------- drivers/gpu/drm/nouveau/nouveau_display.h | 9 ++++---- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 28 +++++++++++++----------- 7 files changed, 75 insertions(+), 84 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 1f08de4241e0..2de589caf508 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -605,15 +605,16 @@ static int nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { struct nv04_display *disp = nv04_display(crtc->dev); - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); + struct drm_framebuffer *fb = crtc->primary->fb; + struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); int ret; - ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM, false); + ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false); if (ret == 0) { if (disp->image[nv_crtc->index]) nouveau_bo_unpin(disp->image[nv_crtc->index]); - nouveau_bo_ref(nvfb->nvbo, &disp->image[nv_crtc->index]); + nouveau_bo_ref(nvbo, &disp->image[nv_crtc->index]); } return ret; @@ -822,8 +823,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index]; + struct nouveau_bo *nvbo; struct drm_framebuffer *drm_fb; - struct nouveau_framebuffer *fb; int arb_burst, arb_lwm; NV_DEBUG(drm, "index %d\n", nv_crtc->index); @@ -839,13 +840,12 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, */ if (atomic) { drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); } else { drm_fb = crtc->primary->fb; - fb = nouveau_framebuffer(crtc->primary->fb); } - nv_crtc->fb.offset = fb->nvbo->bo.offset; + nvbo = nouveau_gem_object(drm_fb->obj[0]); + nv_crtc->fb.offset = nvbo->bo.offset; if (nv_crtc->lut.depth != drm_fb->format->depth) { nv_crtc->lut.depth = drm_fb->format->depth; @@ -1143,8 +1143,9 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; struct drm_device *dev = crtc->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; - struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; + struct drm_framebuffer *old_fb = crtc->primary->fb; + struct nouveau_bo *old_bo = nouveau_gem_object(old_fb->obj[0]); + struct nouveau_bo *new_bo = nouveau_gem_object(fb->obj[0]); struct nv04_page_flip_state *s; struct nouveau_channel *chan; struct nouveau_cli *cli; diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 44ee82d0c9b6..0f4ebefed1fd 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -30,6 +30,7 @@ #include "nouveau_encoder.h" #include "nouveau_connector.h" #include "nouveau_bo.h" +#include "nouveau_gem.h" #include @@ -52,13 +53,13 @@ nv04_display_fini(struct drm_device *dev, bool suspend) /* Un-pin FB and cursors so they'll be evicted to system memory. */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_framebuffer *nouveau_fb; + struct drm_framebuffer *fb = crtc->primary->fb; + struct nouveau_bo *nvbo; - nouveau_fb = nouveau_framebuffer(crtc->primary->fb); - if (!nouveau_fb || !nouveau_fb->nvbo) + if (!fb || !fb->obj[0]) continue; - - nouveau_bo_unpin(nouveau_fb->nvbo); + nvbo = nouveau_gem_object(fb->obj[0]); + nouveau_bo_unpin(nvbo); } list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -104,13 +105,13 @@ nv04_display_init(struct drm_device *dev, bool resume, bool runtime) /* Re-pin FB/cursors. */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_framebuffer *nouveau_fb; + struct drm_framebuffer *fb = crtc->primary->fb; + struct nouveau_bo *nvbo; - nouveau_fb = nouveau_framebuffer(crtc->primary->fb); - if (!nouveau_fb || !nouveau_fb->nvbo) + if (!fb || !fb->obj[0]) continue; - - ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true); + nvbo = nouveau_gem_object(fb->obj[0]); + ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true); if (ret) NV_ERROR(drm, "Could not pin framebuffer\n"); } diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index a3a0a73ae8ab..6248fd1dbc6d 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -31,6 +31,7 @@ #include "nouveau_bo.h" #include "nouveau_connector.h" #include "nouveau_display.h" +#include "nouveau_gem.h" #include "nvreg.h" #include "disp.h" @@ -120,9 +121,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct nvif_object *dev = &drm->client.device.object; struct nouveau_plane *nv_plane = container_of(plane, struct nouveau_plane, base); - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_bo *cur = nv_plane->cur; + struct nouveau_bo *nvbo; bool flip = nv_plane->flip; int soff = NV_PCRTC0_SIZE * nv_crtc->index; int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; @@ -140,17 +141,18 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret) return ret; - ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); + nvbo = nouveau_gem_object(fb->obj[0]); + ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false); if (ret) return ret; - nv_plane->cur = nv_fb->nvbo; + nv_plane->cur = nvbo; nvif_mask(dev, NV_PCRTC_ENGINE_CTRL + soff, NV_CRTC_FSEL_OVERLAY, NV_CRTC_FSEL_OVERLAY); nvif_mask(dev, NV_PCRTC_ENGINE_CTRL + soff2, NV_CRTC_FSEL_OVERLAY, 0); nvif_wr32(dev, NV_PVIDEO_BASE(flip), 0); - nvif_wr32(dev, NV_PVIDEO_OFFSET_BUFF(flip), nv_fb->nvbo->bo.offset); + nvif_wr32(dev, NV_PVIDEO_OFFSET_BUFF(flip), nvbo->bo.offset); nvif_wr32(dev, NV_PVIDEO_SIZE_IN(flip), src_h << 16 | src_w); nvif_wr32(dev, NV_PVIDEO_POINT_IN(flip), src_y << 16 | src_x); nvif_wr32(dev, NV_PVIDEO_DS_DX(flip), (src_w << 20) / crtc_w); @@ -172,7 +174,7 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (format & NV_PVIDEO_FORMAT_PLANAR) { nvif_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0); nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip), - nv_fb->nvbo->bo.offset + fb->offsets[1]); + nvbo->bo.offset + fb->offsets[1]); } nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_STOP, 0); @@ -368,8 +370,8 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object; struct nouveau_plane *nv_plane = container_of(plane, struct nouveau_plane, base); - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); struct nouveau_bo *cur = nv_plane->cur; + struct nouveau_bo *nvbo; uint32_t overlay = 1; int brightness = (nv_plane->brightness - 512) * 62 / 512; int ret, i; @@ -384,11 +386,12 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret) return ret; - ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); + nvbo = nouveau_gem_object(fb->obj[0]); + ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false); if (ret) return ret; - nv_plane->cur = nv_fb->nvbo; + nv_plane->cur = nvbo; nvif_wr32(dev, NV_PVIDEO_OE_STATE, 0); nvif_wr32(dev, NV_PVIDEO_SU_STATE, 0); @@ -396,7 +399,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, for (i = 0; i < 2; i++) { nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i, - nv_fb->nvbo->bo.offset); + nvbo->bo.offset); nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index bb737f9281e6..b5e48ef07b9b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -29,6 +29,7 @@ #include #include "nouveau_bo.h" +#include "nouveau_gem.h" static void nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) @@ -43,7 +44,8 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) { struct nouveau_drm *drm = nouveau_drm(fb->base.dev); struct nv50_wndw_ctxdma *ctxdma; - const u8 kind = fb->nvbo->kind; + struct nouveau_bo *nvbo = nouveau_gem_object(fb->base.obj[0]); + const u8 kind = nvbo->kind; const u32 handle = 0xfb000000 | kind; struct { struct nv_dma_v0 base; @@ -236,6 +238,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, { struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb); struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); + struct nouveau_bo *nvbo = nouveau_gem_object(fb->base.obj[0]); int ret; NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); @@ -243,7 +246,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, if (asyw->state.fb != armw->state.fb || !armw->visible || modeset) { asyw->image.w = fb->base.width; asyw->image.h = fb->base.height; - asyw->image.kind = fb->nvbo->kind; + asyw->image.kind = nvbo->kind; ret = nv50_wndw_atomic_check_acquire_rgb(asyw); if (ret) { @@ -255,9 +258,9 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, if (asyw->image.kind) { asyw->image.layout = 0; if (drm->client.device.info.chipset >= 0xc0) - asyw->image.blockh = fb->nvbo->mode >> 4; + asyw->image.blockh = nvbo->mode >> 4; else - asyw->image.blockh = fb->nvbo->mode; + asyw->image.blockh = nvbo->mode; asyw->image.blocks[0] = fb->base.pitches[0] / 64; asyw->image.pitch[0] = 0; } else { @@ -471,14 +474,15 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) static void nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct nouveau_framebuffer *fb = nouveau_framebuffer(old_state->fb); struct nouveau_drm *drm = nouveau_drm(plane->dev); + struct nouveau_bo *nvbo; NV_ATOMIC(drm, "%s cleanup: %p\n", plane->name, old_state->fb); if (!old_state->fb) return; - nouveau_bo_unpin(fb->nvbo); + nvbo = nouveau_gem_object(old_state->fb->obj[0]); + nouveau_bo_unpin(nvbo); } static int @@ -488,6 +492,7 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) struct nouveau_drm *drm = nouveau_drm(plane->dev); struct nv50_wndw *wndw = nv50_wndw(plane); struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); + struct nouveau_bo *nvbo; struct nv50_head_atom *asyh; struct nv50_wndw_ctxdma *ctxdma; int ret; @@ -496,22 +501,23 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) if (!asyw->state.fb) return 0; - ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM, true); + nvbo = nouveau_gem_object(state->fb->obj[0]); + ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true); if (ret) return ret; if (wndw->ctxdma.parent) { ctxdma = nv50_wndw_ctxdma_new(wndw, fb); if (IS_ERR(ctxdma)) { - nouveau_bo_unpin(fb->nvbo); + nouveau_bo_unpin(nvbo); return PTR_ERR(ctxdma); } asyw->image.handle[0] = ctxdma->object.handle; } - asyw->state.fence = dma_resv_get_excl_rcu(fb->nvbo->bo.base.resv); - asyw->image.offset[0] = fb->nvbo->bo.offset; + asyw->state.fence = dma_resv_get_excl_rcu(nvbo->bo.base.resv); + asyw->image.offset[0] = nvbo->bo.offset; if (wndw->func->prepare) { asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 700817dc4fa0..408b92243629 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -179,37 +180,15 @@ nouveau_display_vblank_init(struct drm_device *dev) return 0; } -static void -nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); - - if (fb->nvbo) - drm_gem_object_put_unlocked(&fb->nvbo->bo.base); - - drm_framebuffer_cleanup(drm_fb); - kfree(fb); -} - -static int -nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); - - return drm_gem_handle_create(file_priv, &fb->nvbo->bo.base, handle); -} - static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { - .destroy = nouveau_user_framebuffer_destroy, - .create_handle = nouveau_user_framebuffer_create_handle, + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, }; int nouveau_framebuffer_new(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, - struct nouveau_bo *nvbo, + struct drm_gem_object *gem, struct nouveau_framebuffer **pfb) { struct nouveau_drm *drm = nouveau_drm(dev); @@ -240,7 +219,7 @@ nouveau_framebuffer_new(struct drm_device *dev, return -ENOMEM; drm_helper_mode_fill_fb_struct(dev, &fb->base, mode_cmd); - fb->nvbo = nvbo; + fb->base.obj[0] = gem; ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs); if (ret) @@ -254,16 +233,14 @@ nouveau_user_framebuffer_create(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd) { struct nouveau_framebuffer *fb; - struct nouveau_bo *nvbo; struct drm_gem_object *gem; int ret; gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (!gem) return ERR_PTR(-ENOENT); - nvbo = nouveau_gem_object(gem); - ret = nouveau_framebuffer_new(dev, mode_cmd, nvbo, &fb); + ret = nouveau_framebuffer_new(dev, mode_cmd, gem, &fb); if (ret == 0) return &fb->base; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index d71de95ece75..4a89b6363793 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -10,7 +10,6 @@ struct nouveau_framebuffer { struct drm_framebuffer base; - struct nouveau_bo *nvbo; }; static inline struct nouveau_framebuffer * @@ -19,9 +18,11 @@ nouveau_framebuffer(struct drm_framebuffer *fb) return container_of(fb, struct nouveau_framebuffer, base); } -int nouveau_framebuffer_new(struct drm_device *, - const struct drm_mode_fb_cmd2 *, - struct nouveau_bo *, struct nouveau_framebuffer **); +int +nouveau_framebuffer_new(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_gem_object *gem, + struct nouveau_framebuffer **pfb); struct nouveau_display { void *priv; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index dcdabd2a1a6d..7333557fe199 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -335,7 +335,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, goto out; } - ret = nouveau_framebuffer_new(dev, &mode_cmd, nvbo, &fb); + ret = nouveau_framebuffer_new(dev, &mode_cmd, &nvbo->bo.base, &fb); if (ret) goto out_unref; @@ -376,12 +376,12 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; info->fbops = &nouveau_fbcon_sw_ops; - info->fix.smem_start = fb->nvbo->bo.mem.bus.base + - fb->nvbo->bo.mem.bus.offset; - info->fix.smem_len = fb->nvbo->bo.mem.num_pages << PAGE_SHIFT; + info->fix.smem_start = nvbo->bo.mem.bus.base + + nvbo->bo.mem.bus.offset; + info->fix.smem_len = nvbo->bo.mem.num_pages << PAGE_SHIFT; - info->screen_base = nvbo_kmap_obj_iovirtual(fb->nvbo); - info->screen_size = fb->nvbo->bo.mem.num_pages << PAGE_SHIFT; + info->screen_base = nvbo_kmap_obj_iovirtual(nvbo); + info->screen_size = nvbo->bo.mem.num_pages << PAGE_SHIFT; drm_fb_helper_fill_info(info, &fbcon->helper, sizes); @@ -393,7 +393,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, /* To allow resizeing without swapping buffers */ NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n", - fb->base.width, fb->base.height, fb->nvbo->bo.offset, nvbo); + fb->base.width, fb->base.height, nvbo->bo.offset, nvbo); vga_switcheroo_client_fb_set(dev->pdev, info); return 0; @@ -401,11 +401,11 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, out_unlock: if (chan) nouveau_vma_del(&fbcon->vma); - nouveau_bo_unmap(fb->nvbo); + nouveau_bo_unmap(nvbo); out_unpin: - nouveau_bo_unpin(fb->nvbo); + nouveau_bo_unpin(nvbo); out_unref: - nouveau_bo_ref(NULL, &fb->nvbo); + nouveau_bo_ref(NULL, &nvbo); out: return ret; } @@ -414,14 +414,16 @@ static int nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) { struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fbcon->helper.fb); + struct nouveau_bo *nvbo; drm_fb_helper_unregister_fbi(&fbcon->helper); drm_fb_helper_fini(&fbcon->helper); - if (nouveau_fb && nouveau_fb->nvbo) { + if (nouveau_fb && nouveau_fb->base.obj[0]) { + nvbo = nouveau_gem_object(nouveau_fb->base.obj[0]); nouveau_vma_del(&fbcon->vma); - nouveau_bo_unmap(nouveau_fb->nvbo); - nouveau_bo_unpin(nouveau_fb->nvbo); + nouveau_bo_unmap(nvbo); + nouveau_bo_unpin(nvbo); drm_framebuffer_put(&nouveau_fb->base); } -- cgit v1.2.3 From 559c9eb6a6698db8ba355edf79afd7c10b89026c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 6 Feb 2020 11:19:42 +0100 Subject: drm/nouveau/kms: Remove struct nouveau_framebuffer After its cleanup, struct nouveau_framebuffer is only a wrapper around struct drm_framebuffer. Use the latter directly. Signed-off-by: Thomas Zimmermann Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 26 +++++++++++++------------- drivers/gpu/drm/nouveau/nouveau_display.c | 14 +++++++------- drivers/gpu/drm/nouveau/nouveau_display.h | 12 +----------- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 14 +++++++------- 4 files changed, 28 insertions(+), 38 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index b5e48ef07b9b..55e764bff381 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -40,11 +40,11 @@ nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) } static struct nv50_wndw_ctxdma * -nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) +nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) { - struct nouveau_drm *drm = nouveau_drm(fb->base.dev); + struct nouveau_drm *drm = nouveau_drm(fb->dev); struct nv50_wndw_ctxdma *ctxdma; - struct nouveau_bo *nvbo = nouveau_gem_object(fb->base.obj[0]); + struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]); const u8 kind = nvbo->kind; const u32 handle = 0xfb000000 | kind; struct { @@ -236,16 +236,16 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { - struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb); + struct drm_framebuffer *fb = asyw->state.fb; struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); - struct nouveau_bo *nvbo = nouveau_gem_object(fb->base.obj[0]); + struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]); int ret; NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); - if (asyw->state.fb != armw->state.fb || !armw->visible || modeset) { - asyw->image.w = fb->base.width; - asyw->image.h = fb->base.height; + if (fb != armw->state.fb || !armw->visible || modeset) { + asyw->image.w = fb->width; + asyw->image.h = fb->height; asyw->image.kind = nvbo->kind; ret = nv50_wndw_atomic_check_acquire_rgb(asyw); @@ -261,13 +261,13 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->image.blockh = nvbo->mode >> 4; else asyw->image.blockh = nvbo->mode; - asyw->image.blocks[0] = fb->base.pitches[0] / 64; + asyw->image.blocks[0] = fb->pitches[0] / 64; asyw->image.pitch[0] = 0; } else { asyw->image.layout = 1; asyw->image.blockh = 0; asyw->image.blocks[0] = 0; - asyw->image.pitch[0] = fb->base.pitches[0]; + asyw->image.pitch[0] = fb->pitches[0]; } if (!asyh->state.async_flip) @@ -488,7 +488,7 @@ nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) static int nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) { - struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb); + struct drm_framebuffer *fb = state->fb; struct nouveau_drm *drm = nouveau_drm(plane->dev); struct nv50_wndw *wndw = nv50_wndw(plane); struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); @@ -497,11 +497,11 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) struct nv50_wndw_ctxdma *ctxdma; int ret; - NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb); + NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, fb); if (!asyw->state.fb) return 0; - nvbo = nouveau_gem_object(state->fb->obj[0]); + nvbo = nouveau_gem_object(fb->obj[0]); ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 408b92243629..d732566caf60 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -189,10 +189,10 @@ int nouveau_framebuffer_new(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *gem, - struct nouveau_framebuffer **pfb) + struct drm_framebuffer **pfb) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_framebuffer *fb; + struct drm_framebuffer *fb; int ret; /* YUV overlays have special requirements pre-NV50 */ @@ -218,10 +218,10 @@ nouveau_framebuffer_new(struct drm_device *dev, if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL))) return -ENOMEM; - drm_helper_mode_fill_fb_struct(dev, &fb->base, mode_cmd); - fb->base.obj[0] = gem; + drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); + fb->obj[0] = gem; - ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs); + ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); if (ret) kfree(fb); return ret; @@ -232,7 +232,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) { - struct nouveau_framebuffer *fb; + struct drm_framebuffer *fb; struct drm_gem_object *gem; int ret; @@ -242,7 +242,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev, ret = nouveau_framebuffer_new(dev, mode_cmd, gem, &fb); if (ret == 0) - return &fb->base; + return fb; drm_gem_object_put_unlocked(gem); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a89b6363793..c745213d9bdf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -8,21 +8,11 @@ #include -struct nouveau_framebuffer { - struct drm_framebuffer base; -}; - -static inline struct nouveau_framebuffer * -nouveau_framebuffer(struct drm_framebuffer *fb) -{ - return container_of(fb, struct nouveau_framebuffer, base); -} - int nouveau_framebuffer_new(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *gem, - struct nouveau_framebuffer **pfb); + struct drm_framebuffer **pfb); struct nouveau_display { void *priv; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 7333557fe199..3d11b84d4cf9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -312,7 +312,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, struct nouveau_drm *drm = nouveau_drm(dev); struct nvif_device *device = &drm->client.device; struct fb_info *info; - struct nouveau_framebuffer *fb; + struct drm_framebuffer *fb; struct nouveau_channel *chan; struct nouveau_bo *nvbo; struct drm_mode_fb_cmd2 mode_cmd; @@ -367,7 +367,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, } /* setup helper */ - fbcon->helper.fb = &fb->base; + fbcon->helper.fb = fb; if (!chan) info->flags = FBINFO_HWACCEL_DISABLED; @@ -393,7 +393,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, /* To allow resizeing without swapping buffers */ NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n", - fb->base.width, fb->base.height, nvbo->bo.offset, nvbo); + fb->width, fb->height, nvbo->bo.offset, nvbo); vga_switcheroo_client_fb_set(dev->pdev, info); return 0; @@ -413,18 +413,18 @@ out: static int nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) { - struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fbcon->helper.fb); + struct drm_framebuffer *fb = fbcon->helper.fb; struct nouveau_bo *nvbo; drm_fb_helper_unregister_fbi(&fbcon->helper); drm_fb_helper_fini(&fbcon->helper); - if (nouveau_fb && nouveau_fb->base.obj[0]) { - nvbo = nouveau_gem_object(nouveau_fb->base.obj[0]); + if (fb && fb->obj[0]) { + nvbo = nouveau_gem_object(fb->obj[0]); nouveau_vma_del(&fbcon->vma); nouveau_bo_unmap(nvbo); nouveau_bo_unpin(nvbo); - drm_framebuffer_put(&nouveau_fb->base); + drm_framebuffer_put(fb); } return 0; -- cgit v1.2.3 From fd44028ff145ffb2d03c877d74f479da04ac2c62 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 11 Feb 2020 08:45:04 +1000 Subject: drm/nouveau/acr: ensure falcon providing acr functions is bootstrapped first Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c index 8eb2a930a9b5..e4866a02e457 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c @@ -250,6 +250,11 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev) list_add_tail(&lsf->head, &acr->lsf); } + /* Ensure the falcon that'll provide ACR functions is booted first. */ + lsf = nvkm_acr_falcon(device); + if (lsf) + list_move(&lsf->head, &acr->lsf); + if (!acr->wpr_fw || acr->wpr_comp) wpr_size = acr->func->wpr_layout(acr); -- cgit v1.2.3 From c586f30bf74cb580c1748222b05a0bad57d7dcd4 Mon Sep 17 00:00:00 2001 From: James Jones Date: Mon, 10 Feb 2020 15:15:53 -0800 Subject: drm/nouveau/kms: Add format mod prop to base/ovly/nvdisp Advertise support for the full list of format modifiers supported by each class of NVIDIA desktop GPU display hardware. Stash the array of modifiers in the nouveau_display struct for use when validating userspace framebuffer creation requests, which will be supportd in a subsequent change. Signed-off-by: James Jones Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 7 ++-- drivers/gpu/drm/nouveau/dispnv50/disp.c | 59 +++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/disp.h | 4 ++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 27 ++++++++++++- drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c | 17 +++++++++ drivers/gpu/drm/nouveau/nouveau_display.h | 2 + 6 files changed, 112 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index ee782151d332..511258bfbcbc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -263,7 +263,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, struct nv50_disp_base_channel_dma_v0 args = { .head = head, }; - struct nv50_disp *disp = nv50_disp(drm->dev); + struct nouveau_display *disp = nouveau_display(drm->dev); + struct nv50_disp *disp50 = nv50_disp(drm->dev); struct nv50_wndw *wndw; int ret; @@ -273,9 +274,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, if (*pwndw = wndw, ret) return ret; - ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + ret = nv50_dmac_create(&drm->client.device, &disp->disp.object, &oclass, head, &args, sizeof(args), - disp->sync->bo.offset, &wndw->wndw); + disp50->sync->bo.offset, &wndw->wndw); if (ret) { NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 6be9df1820c5..8a79f06e9e26 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2456,6 +2456,15 @@ nv50_display_create(struct drm_device *dev) if (ret) goto out; + /* Assign the correct format modifiers */ + if (disp->disp->object.oclass >= TU102_DISP) + nouveau_display(dev)->format_modifiers = wndwc57e_modifiers; + else + if (disp->disp->object.oclass >= GF110_DISP) + nouveau_display(dev)->format_modifiers = disp90xx_modifiers; + else + nouveau_display(dev)->format_modifiers = disp50xx_modifiers; + /* create crtc objects to represent the hw heads */ if (disp->disp->object.oclass >= GV100_DISP) crtcs = nvif_rd32(&device->object, 0x610060) & 0xff; @@ -2551,3 +2560,53 @@ out: nv50_display_destroy(dev); return ret; } + +/****************************************************************************** + * Format modifiers + *****************************************************************************/ + +/**************************************************************** + * Log2(block height) ----------------------------+ * + * Page Kind ----------------------------------+ | * + * Gob Height/Page Kind Generation ------+ | | * + * Sector layout -------+ | | | * + * Compression ------+ | | | | */ +const u64 disp50xx_modifiers[] = { /* | | | | | */ + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 5), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 5), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 5), + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +/**************************************************************** + * Log2(block height) ----------------------------+ * + * Page Kind ----------------------------------+ | * + * Gob Height/Page Kind Generation ------+ | | * + * Sector layout -------+ | | | * + * Compression ------+ | | | | */ +const u64 disp90xx_modifiers[] = { /* | | | | | */ + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 5), + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index d54fe00ac3a3..1743c3a76216 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -78,6 +78,10 @@ void nv50_dmac_destroy(struct nv50_dmac *); u32 *evo_wait(struct nv50_dmac *, int nr); void evo_kick(u32 *, struct nv50_dmac *); +extern const u64 disp50xx_modifiers[]; +extern const u64 disp90xx_modifiers[]; +extern const u64 wndwc57e_modifiers[]; + #define evo_mthd(p, m, s) do { \ const u32 _m = (m), _s = (s); \ if (drm_debug_enabled(DRM_UT_KMS)) \ diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 55e764bff381..1425a9ca86cf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -609,6 +609,29 @@ nv50_wndw_destroy(struct drm_plane *plane) kfree(wndw); } +/* This function assumes the format has already been validated against the plane + * and the modifier was validated against the device-wides modifier list at FB + * creation time. + */ +static bool nv50_plane_format_mod_supported(struct drm_plane *plane, + u32 format, u64 modifier) +{ + struct nouveau_drm *drm = nouveau_drm(plane->dev); + uint8_t i; + + if (drm->client.device.info.chipset < 0xc0) { + const struct drm_format_info *info = drm_format_info(format); + const uint8_t kind = (modifier >> 12) & 0xff; + + if (!format) return false; + + for (i = 0; i < info->num_planes; i++) + if ((info->cpp[i] != 4) && kind != 0x70) return false; + } + + return true; +} + const struct drm_plane_funcs nv50_wndw = { .update_plane = drm_atomic_helper_update_plane, @@ -617,6 +640,7 @@ nv50_wndw = { .reset = nv50_wndw_reset, .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, .atomic_destroy_state = nv50_wndw_atomic_destroy_state, + .format_mod_supported = nv50_plane_format_mod_supported, }; static int @@ -664,7 +688,8 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, for (nformat = 0; format[nformat]; nformat++); ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, - format, nformat, NULL, + format, nformat, + nouveau_display(dev)->format_modifiers, type, "%s-%d", name, index); if (ret) { kfree(*pwndw); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c index 35c9c52fab26..1d64741595ba 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c @@ -173,6 +173,23 @@ wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) return true; } +/**************************************************************** + * Log2(block height) ----------------------------+ * + * Page Kind ----------------------------------+ | * + * Gob Height/Page Kind Generation ------+ | | * + * Sector layout -------+ | | | * + * Compression ------+ | | | | */ +const u64 wndwc57e_modifiers[] = { /* | | | | | */ + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5), + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const struct nv50_wndw_func wndwc57e = { .acquire = wndwc37e_acquire, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index c745213d9bdf..1dd69c50a4ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -32,6 +32,8 @@ struct nouveau_display { struct drm_property *color_vibrance_property; struct drm_atomic_state *suspend; + + const u64 *format_modifiers; }; static inline struct nouveau_display * -- cgit v1.2.3 From 4f5746c863db1a98535964009da19c6f7a842c55 Mon Sep 17 00:00:00 2001 From: James Jones Date: Mon, 10 Feb 2020 15:15:54 -0800 Subject: drm/nouveau/kms: Check framebuffer size against bo Make sure framebuffer dimensions and tiling parameters will not result in accesses beyond the end of the GEM buffer they are bound to. v3: Return EINVAL when creating FB against BO with unsupported tiling v5: Resolved against nouveau_framebuffer cleanup Signed-off-by: James Jones Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.c | 98 +++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index d732566caf60..7d6b344047ab 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -185,6 +185,76 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { .create_handle = drm_gem_fb_create_handle, }; +static inline uint32_t +nouveau_get_width_in_blocks(uint32_t stride) +{ + /* GOBs per block in the x direction is always one, and GOBs are + * 64 bytes wide + */ + static const uint32_t log_block_width = 6; + + return (stride + (1 << log_block_width) - 1) >> log_block_width; +} + +static inline uint32_t +nouveau_get_height_in_blocks(struct nouveau_drm *drm, + uint32_t height, + uint32_t log_block_height_in_gobs) +{ + uint32_t log_gob_height; + uint32_t log_block_height; + + BUG_ON(drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA); + + if (drm->client.device.info.family < NV_DEVICE_INFO_V0_FERMI) + log_gob_height = 2; + else + log_gob_height = 3; + + log_block_height = log_block_height_in_gobs + log_gob_height; + + return (height + (1 << log_block_height) - 1) >> log_block_height; +} + +static int +nouveau_check_bl_size(struct nouveau_drm *drm, struct nouveau_bo *nvbo, + uint32_t offset, uint32_t stride, uint32_t h, + uint32_t tile_mode) +{ + uint32_t gob_size, bw, bh; + uint64_t bl_size; + + BUG_ON(drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA); + + if (drm->client.device.info.chipset >= 0xc0) { + if (tile_mode & 0xF) + return -EINVAL; + tile_mode >>= 4; + } + + if (tile_mode & 0xFFFFFFF0) + return -EINVAL; + + if (drm->client.device.info.family < NV_DEVICE_INFO_V0_FERMI) + gob_size = 256; + else + gob_size = 512; + + bw = nouveau_get_width_in_blocks(stride); + bh = nouveau_get_height_in_blocks(drm, h, tile_mode); + + bl_size = bw * bh * (1 << tile_mode) * gob_size; + + DRM_DEBUG_KMS("offset=%u stride=%u h=%u tile_mode=0x%02x bw=%u bh=%u gob_size=%u bl_size=%llu size=%lu\n", + offset, stride, h, tile_mode, bw, bh, gob_size, bl_size, + nvbo->bo.mem.size); + + if (bl_size + offset > nvbo->bo.mem.size) + return -ERANGE; + + return 0; +} + int nouveau_framebuffer_new(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, @@ -192,7 +262,10 @@ nouveau_framebuffer_new(struct drm_device *dev, struct drm_framebuffer **pfb) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct drm_framebuffer *fb; + const struct drm_format_info *info; + unsigned int width, height, i; int ret; /* YUV overlays have special requirements pre-NV50 */ @@ -215,6 +288,31 @@ nouveau_framebuffer_new(struct drm_device *dev, return -EINVAL; } + info = drm_get_format_info(dev, mode_cmd); + + for (i = 0; i < info->num_planes; i++) { + width = drm_format_info_plane_width(info, + mode_cmd->width, + i); + height = drm_format_info_plane_height(info, + mode_cmd->height, + i); + + if (nvbo->kind) { + ret = nouveau_check_bl_size(drm, nvbo, + mode_cmd->offsets[i], + mode_cmd->pitches[i], + height, nvbo->mode); + if (ret) + return ret; + } else { + uint32_t size = mode_cmd->pitches[i] * height; + + if (size + mode_cmd->offsets[i] > nvbo->bo.mem.size) + return -ERANGE; + } + } + if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL))) return -ENOMEM; -- cgit v1.2.3 From fa4f4c213f5f7807360c41f2501a3031a9940f3a Mon Sep 17 00:00:00 2001 From: James Jones Date: Mon, 10 Feb 2020 15:15:55 -0800 Subject: drm/nouveau/kms: Support NVIDIA format modifiers Allow setting the block layout of a nouveau FB object using DRM format modifiers. When specified, the format modifier block layout and kind overrides the GEM buffer's implicit layout and kind. The specified format modifier is validated against the list of modifiers supported by the target display hardware. v2: Used Tesla family instead of NV50 chipset compare v4: Do not cache kind, tile_mode in nouveau_framebuffer v5: Resolved against nouveau_framebuffer cleanup Signed-off-by: James Jones Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 20 ++++--- drivers/gpu/drm/nouveau/nouveau_display.c | 89 ++++++++++++++++++++++++++++++- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++ 3 files changed, 104 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 1425a9ca86cf..e25ead56052c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -44,9 +44,9 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) { struct nouveau_drm *drm = nouveau_drm(fb->dev); struct nv50_wndw_ctxdma *ctxdma; - struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]); - const u8 kind = nvbo->kind; - const u32 handle = 0xfb000000 | kind; + u32 handle; + u32 unused; + u8 kind; struct { struct nv_dma_v0 base; union { @@ -58,6 +58,9 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) u32 argc = sizeof(args.base); int ret; + nouveau_framebuffer_get_layout(fb, &unused, &kind); + handle = 0xfb000000 | kind; + list_for_each_entry(ctxdma, &wndw->ctxdma.list, head) { if (ctxdma->object.handle == handle) return ctxdma; @@ -238,15 +241,18 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, { struct drm_framebuffer *fb = asyw->state.fb; struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); - struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]); + uint8_t kind; + uint32_t tile_mode; int ret; NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); if (fb != armw->state.fb || !armw->visible || modeset) { + nouveau_framebuffer_get_layout(fb, &tile_mode, &kind); + asyw->image.w = fb->width; asyw->image.h = fb->height; - asyw->image.kind = nvbo->kind; + asyw->image.kind = kind; ret = nv50_wndw_atomic_check_acquire_rgb(asyw); if (ret) { @@ -258,9 +264,9 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, if (asyw->image.kind) { asyw->image.layout = 0; if (drm->client.device.info.chipset >= 0xc0) - asyw->image.blockh = nvbo->mode >> 4; + asyw->image.blockh = tile_mode >> 4; else - asyw->image.blockh = nvbo->mode; + asyw->image.blockh = tile_mode; asyw->image.blocks[0] = fb->pitches[0] / 64; asyw->image.pitch[0] = 0; } else { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 7d6b344047ab..496c4621cc78 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -185,6 +185,76 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { .create_handle = drm_gem_fb_create_handle, }; +static void +nouveau_decode_mod(struct nouveau_drm *drm, + uint64_t modifier, + uint32_t *tile_mode, + uint8_t *kind) +{ + BUG_ON(!tile_mode || !kind); + + if (modifier == DRM_FORMAT_MOD_LINEAR) { + /* tile_mode will not be used in this case */ + *tile_mode = 0; + *kind = 0; + } else { + /* + * Extract the block height and kind from the corresponding + * modifier fields. See drm_fourcc.h for details. + */ + *tile_mode = (uint32_t)(modifier & 0xF); + *kind = (uint8_t)((modifier >> 12) & 0xFF); + + if (drm->client.device.info.chipset >= 0xc0) + *tile_mode <<= 4; + } +} + +void +nouveau_framebuffer_get_layout(struct drm_framebuffer *fb, + uint32_t *tile_mode, + uint8_t *kind) +{ + if (fb->flags & DRM_MODE_FB_MODIFIERS) { + struct nouveau_drm *drm = nouveau_drm(fb->dev); + + nouveau_decode_mod(drm, fb->modifier, tile_mode, kind); + } else { + const struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]); + + *tile_mode = nvbo->mode; + *kind = nvbo->kind; + } +} + +static int +nouveau_validate_decode_mod(struct nouveau_drm *drm, + uint64_t modifier, + uint32_t *tile_mode, + uint8_t *kind) +{ + struct nouveau_display *disp = nouveau_display(drm->dev); + int mod; + + if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) { + return -EINVAL; + } + + BUG_ON(!disp->format_modifiers); + + for (mod = 0; + (disp->format_modifiers[mod] != DRM_FORMAT_MOD_INVALID) && + (disp->format_modifiers[mod] != modifier); + mod++); + + if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID) + return -EINVAL; + + nouveau_decode_mod(drm, modifier, tile_mode, kind); + + return 0; +} + static inline uint32_t nouveau_get_width_in_blocks(uint32_t stride) { @@ -266,6 +336,8 @@ nouveau_framebuffer_new(struct drm_device *dev, struct drm_framebuffer *fb; const struct drm_format_info *info; unsigned int width, height, i; + uint32_t tile_mode; + uint8_t kind; int ret; /* YUV overlays have special requirements pre-NV50 */ @@ -288,6 +360,18 @@ nouveau_framebuffer_new(struct drm_device *dev, return -EINVAL; } + if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { + if (nouveau_validate_decode_mod(drm, mode_cmd->modifier[0], + &tile_mode, &kind)) { + DRM_DEBUG_KMS("Unsupported modifier: 0x%llx\n", + mode_cmd->modifier[0]); + return -EINVAL; + } + } else { + tile_mode = nvbo->mode; + kind = nvbo->kind; + } + info = drm_get_format_info(dev, mode_cmd); for (i = 0; i < info->num_planes; i++) { @@ -298,11 +382,11 @@ nouveau_framebuffer_new(struct drm_device *dev, mode_cmd->height, i); - if (nvbo->kind) { + if (kind) { ret = nouveau_check_bl_size(drm, nvbo, mode_cmd->offsets[i], mode_cmd->pitches[i], - height, nvbo->mode); + height, tile_mode); if (ret) return ret; } else { @@ -592,6 +676,7 @@ nouveau_display_create(struct drm_device *dev) dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; + dev->mode_config.allow_fb_modifiers = true; if (drm->client.device.info.chipset < 0x11) dev->mode_config.async_page_flip = false; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 1dd69c50a4ed..6e0d900441d6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -62,6 +62,10 @@ int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *, void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *); +void +nouveau_framebuffer_get_layout(struct drm_framebuffer *fb, uint32_t *tile_mode, + uint8_t *kind); + struct drm_framebuffer * nouveau_user_framebuffer_create(struct drm_device *, struct drm_file *, const struct drm_mode_fb_cmd2 *); -- cgit v1.2.3 From f02ca8425a5c49a3751ca0045f1ec14b3c84a05f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 11 Feb 2020 17:34:58 +1000 Subject: drm/nouveau/core: add nvkm_subdev_new_() for bare subdevs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 11 +++++++++++ 2 files changed, 13 insertions(+) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h index 1218f28c14ba..76288c682e9e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -24,6 +24,8 @@ struct nvkm_subdev_func { }; extern const char *nvkm_subdev_name[NVKM_SUBDEV_NR]; +int nvkm_subdev_new_(const struct nvkm_subdev_func *, struct nvkm_device *, + int index, struct nvkm_subdev **); void nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *, int index, struct nvkm_subdev *); void nvkm_subdev_del(struct nvkm_subdev **); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index 79a8f9d305c5..49d468b45d3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -221,3 +221,14 @@ nvkm_subdev_ctor(const struct nvkm_subdev_func *func, __mutex_init(&subdev->mutex, name, &nvkm_subdev_lock_class[index]); subdev->debug = nvkm_dbgopt(device->dbgopt, name); } + +int +nvkm_subdev_new_(const struct nvkm_subdev_func *func, + struct nvkm_device *device, int index, + struct nvkm_subdev **psubdev) +{ + if (!(*psubdev = kzalloc(sizeof(**psubdev), GFP_KERNEL))) + return -ENOMEM; + nvkm_subdev_ctor(func, device, index, *psubdev); + return 0; +} -- cgit v1.2.3 From d2bcfce7f8a4ba8df28d3bebb81225bd7f9c046f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 11 Feb 2020 17:36:49 +1000 Subject: drm/nouveau/ibus: use nvkm_subdev_new_() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c | 6 +----- 6 files changed, 6 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c index d80dbc8f09b2..2340040942c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c @@ -114,9 +114,5 @@ int gf100_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gf100_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gf100_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c index 3905a80da811..1124dadac145 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c @@ -43,9 +43,5 @@ int gf117_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gf117_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gf117_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c index 9025ed1bd2a9..f3915f85838e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c @@ -117,9 +117,5 @@ int gk104_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gk104_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gk104_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c index 1a4ab825852c..187d544378b0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c @@ -81,9 +81,5 @@ int gk20a_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gk20a_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gk20a_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c index c63328152bfa..0f1f0ad6377e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c @@ -32,9 +32,5 @@ int gm200_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gm200_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gm200_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c index 39db90aa2c80..0347b367cefe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c @@ -51,9 +51,5 @@ int gp10b_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gp10b_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gp10b_ibus, device, index, pibus); } -- cgit v1.2.3 From fb172f5fe880cd0ddb4370b2fcc9ad4848c98bbb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 7 Feb 2020 12:39:25 +1000 Subject: drm/nouveau/gr/gk20a: move MODULE_FIRMWARE firmware definitions Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_platform.c | 11 ----------- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 039e23548e08..23cd43a7fd19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c @@ -95,14 +95,3 @@ struct platform_driver nouveau_platform_driver = { .probe = nouveau_platform_probe, .remove = nouveau_platform_remove, }; - -#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) || IS_ENABLED(CONFIG_ARCH_TEGRA_132_SOC) -MODULE_FIRMWARE("nvidia/gk20a/fecs_data.bin"); -MODULE_FIRMWARE("nvidia/gk20a/fecs_inst.bin"); -MODULE_FIRMWARE("nvidia/gk20a/gpccs_data.bin"); -MODULE_FIRMWARE("nvidia/gk20a/gpccs_inst.bin"); -MODULE_FIRMWARE("nvidia/gk20a/sw_bundle_init.bin"); -MODULE_FIRMWARE("nvidia/gk20a/sw_ctx.bin"); -MODULE_FIRMWARE("nvidia/gk20a/sw_method_init.bin"); -MODULE_FIRMWARE("nvidia/gk20a/sw_nonctx.bin"); -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index 4209b24a46d7..ec330d791d15 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -319,6 +319,17 @@ gk20a_gr_load_sw(struct gf100_gr *gr, const char *path, int ver) return 0; } +#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) || IS_ENABLED(CONFIG_ARCH_TEGRA_132_SOC) +MODULE_FIRMWARE("nvidia/gk20a/fecs_data.bin"); +MODULE_FIRMWARE("nvidia/gk20a/fecs_inst.bin"); +MODULE_FIRMWARE("nvidia/gk20a/gpccs_data.bin"); +MODULE_FIRMWARE("nvidia/gk20a/gpccs_inst.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_bundle_init.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_ctx.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_method_init.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_nonctx.bin"); +#endif + static int gk20a_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif) { -- cgit v1.2.3 From 2dd4d163cd9c15432524aa9863155bc03a821361 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Feb 2020 13:55:23 +1000 Subject: drm/nouveau: remove open-coded version of remove_conflicting_pci_framebuffers() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ca4087f5a15b..eb10c80ed853 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -681,8 +681,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, { struct nvkm_device *device; struct drm_device *drm_dev; - struct apertures_struct *aper; - bool boot = false; int ret; if (vga_switcheroo_client_probe_defer(pdev)) @@ -699,32 +697,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev, nvkm_device_del(&device); /* Remove conflicting drivers (vesafb, efifb etc). */ - aper = alloc_apertures(3); - if (!aper) - return -ENOMEM; - - aper->ranges[0].base = pci_resource_start(pdev, 1); - aper->ranges[0].size = pci_resource_len(pdev, 1); - aper->count = 1; - - if (pci_resource_len(pdev, 2)) { - aper->ranges[aper->count].base = pci_resource_start(pdev, 2); - aper->ranges[aper->count].size = pci_resource_len(pdev, 2); - aper->count++; - } - - if (pci_resource_len(pdev, 3)) { - aper->ranges[aper->count].base = pci_resource_start(pdev, 3); - aper->ranges[aper->count].size = pci_resource_len(pdev, 3); - aper->count++; - } - -#ifdef CONFIG_X86 - boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif - if (nouveau_modeset != 2) - drm_fb_helper_remove_conflicting_framebuffers(aper, "nouveaufb", boot); - kfree(aper); + ret = remove_conflicting_pci_framebuffers(pdev, "nouveaufb"); + if (ret) + return ret; ret = nvkm_device_pci_new(pdev, nouveau_config, nouveau_debug, true, true, ~0ULL, &device); -- cgit v1.2.3 From b950c8c5d082d822b0134d1fc058101ab346e503 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 29 Jan 2020 18:27:39 +1000 Subject: drm/nouveau/bios: move ACPI _ROM handling Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 54 ------------------ drivers/gpu/drm/nouveau/nouveau_acpi.h | 4 -- .../gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c | 65 ++++++++++++++++------ 3 files changed, 47 insertions(+), 76 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index fe3a10255c36..65440ec9b6f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -49,7 +49,6 @@ static struct nouveau_dsm_priv { bool optimus_flags_detected; bool optimus_skip_dsm; acpi_handle dhandle; - acpi_handle rom_handle; } nouveau_dsm_priv; bool nouveau_is_optimus(void) { @@ -385,59 +384,6 @@ void nouveau_unregister_dsm_handler(void) {} void nouveau_switcheroo_optimus_dsm(void) {} #endif -/* retrieve the ROM in 4k blocks */ -static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, - int offset, int len) -{ - acpi_status status; - union acpi_object rom_arg_elements[2], *obj; - struct acpi_object_list rom_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - - rom_arg.count = 2; - rom_arg.pointer = &rom_arg_elements[0]; - - rom_arg_elements[0].type = ACPI_TYPE_INTEGER; - rom_arg_elements[0].integer.value = offset; - - rom_arg_elements[1].type = ACPI_TYPE_INTEGER; - rom_arg_elements[1].integer.value = len; - - status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); - if (ACPI_FAILURE(status)) { - pr_info("failed to evaluate ROM got %s\n", - acpi_format_exception(status)); - return -ENODEV; - } - obj = (union acpi_object *)buffer.pointer; - len = min(len, (int)obj->buffer.length); - memcpy(bios+offset, obj->buffer.pointer, len); - kfree(buffer.pointer); - return len; -} - -bool nouveau_acpi_rom_supported(struct device *dev) -{ - acpi_status status; - acpi_handle dhandle, rom_handle; - - dhandle = ACPI_HANDLE(dev); - if (!dhandle) - return false; - - status = acpi_get_handle(dhandle, "_ROM", &rom_handle); - if (ACPI_FAILURE(status)) - return false; - - nouveau_dsm_priv.rom_handle = rom_handle; - return true; -} - -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) -{ - return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); -} - void * nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouveau/nouveau_acpi.h index 1e6e8a8c0455..330f9b837066 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h @@ -10,8 +10,6 @@ bool nouveau_is_v1_dsm(void); void nouveau_register_dsm_handler(void); void nouveau_unregister_dsm_handler(void); void nouveau_switcheroo_optimus_dsm(void); -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); -bool nouveau_acpi_rom_supported(struct device *); void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *); #else static inline bool nouveau_is_optimus(void) { return false; }; @@ -19,8 +17,6 @@ static inline bool nouveau_is_v1_dsm(void) { return false; }; static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} static inline void nouveau_switcheroo_optimus_dsm(void) {} -static inline bool nouveau_acpi_rom_supported(struct device *dev) { return false; } -static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; } #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c index 06572f8ce914..f9c427559538 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c @@ -22,22 +22,39 @@ */ #include "priv.h" -#if defined(CONFIG_ACPI) && defined(CONFIG_X86) -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); -bool nouveau_acpi_rom_supported(struct device *); -#else -static inline bool -nouveau_acpi_rom_supported(struct device *dev) +static int +acpi_read_bios(acpi_handle rom_handle, u8 *bios, u32 offset, u32 length) { - return false; -} +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_status status; + union acpi_object rom_arg_elements[2], *obj; + struct acpi_object_list rom_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; -static inline int -nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) -{ + rom_arg.count = 2; + rom_arg.pointer = &rom_arg_elements[0]; + + rom_arg_elements[0].type = ACPI_TYPE_INTEGER; + rom_arg_elements[0].integer.value = offset; + + rom_arg_elements[1].type = ACPI_TYPE_INTEGER; + rom_arg_elements[1].integer.value = length; + + status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); + if (ACPI_FAILURE(status)) { + pr_info("failed to evaluate ROM got %s\n", + acpi_format_exception(status)); + return -ENODEV; + } + obj = (union acpi_object *)buffer.pointer; + length = min(length, obj->buffer.length); + memcpy(bios+offset, obj->buffer.pointer, length); + kfree(buffer.pointer); + return length; +#else return -EINVAL; -} #endif +} /* This version of the shadow function disobeys the ACPI spec and tries * to fetch in units of more than 4KiB at a time. This is a LOT faster @@ -51,7 +68,7 @@ acpi_read_fast(void *data, u32 offset, u32 length, struct nvkm_bios *bios) u32 fetch = limit - start; if (nvbios_extend(bios, limit) >= 0) { - int ret = nouveau_acpi_get_bios_chunk(bios->data, start, fetch); + int ret = acpi_read_bios(data, bios->data, start, fetch); if (ret == fetch) return fetch; } @@ -73,9 +90,8 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios) if (nvbios_extend(bios, limit) >= 0) { while (start + fetch < limit) { - int ret = nouveau_acpi_get_bios_chunk(bios->data, - start + fetch, - 0x1000); + int ret = acpi_read_bios(data, bios->data, + start + fetch, 0x1000); if (ret != 0x1000) break; fetch += 0x1000; @@ -88,9 +104,22 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios) static void * acpi_init(struct nvkm_bios *bios, const char *name) { - if (!nouveau_acpi_rom_supported(bios->subdev.device->dev)) +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_status status; + acpi_handle dhandle, rom_handle; + + dhandle = ACPI_HANDLE(bios->subdev.device->dev); + if (!dhandle) return ERR_PTR(-ENODEV); - return NULL; + + status = acpi_get_handle(dhandle, "_ROM", &rom_handle); + if (ACPI_FAILURE(status)) + return ERR_PTR(-ENODEV); + + return rom_handle; +#else + return ERR_PTR(-ENODEV); +#endif } const struct nvbios_source -- cgit v1.2.3 From 9c1c08a68dcdea3a933948b4e7927bdbc56aac4c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Feb 2020 09:39:34 +1000 Subject: drm/nouveau/disp/gv100-: expose capabilities class Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c | 60 ++++++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h | 3 ++ .../gpu/drm/nouveau/nvkm/engine/disp/roottu102.c | 1 + 6 files changed, 69 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 30659747ffe8..2c79beb41126 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -89,6 +89,8 @@ #define GV100_DISP /* cl5070.h */ 0x0000c370 #define TU102_DISP /* cl5070.h */ 0x0000c570 +#define GV100_DISP_CAPS 0x0000c373 + #define NV31_MPEG 0x00003174 #define G82_MPEG 0x00008274 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 0d584d0da59c..f7af648e0c17 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -74,6 +74,8 @@ nvkm-y += nvkm/engine/disp/rootgp102.o nvkm-y += nvkm/engine/disp/rootgv100.o nvkm-y += nvkm/engine/disp/roottu102.o +nvkm-y += nvkm/engine/disp/capsgv100.o + nvkm-y += nvkm/engine/disp/channv50.o nvkm-y += nvkm/engine/disp/changf119.o nvkm-y += nvkm/engine/disp/changv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c new file mode 100644 index 000000000000..5026e530f4bb --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c @@ -0,0 +1,60 @@ +/* + * Copyright 2020 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. + */ +#define gv100_disp_caps(p) container_of((p), struct gv100_disp_caps, object) +#include "rootnv50.h" + +struct gv100_disp_caps { + struct nvkm_object object; + struct nv50_disp *disp; +}; + +static int +gv100_disp_caps_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) +{ + struct gv100_disp_caps *caps = gv100_disp_caps(object); + struct nvkm_device *device = caps->disp->base.engine.subdev.device; + *type = NVKM_OBJECT_MAP_IO; + *addr = 0x640000 + device->func->resource_addr(device, 0); + *size = 0x1000; + return 0; +} + +static const struct nvkm_object_func +gv100_disp_caps = { + .map = gv100_disp_caps_map, +}; + +int +gv100_disp_caps_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + struct gv100_disp_caps *caps; + + if (!(caps = kzalloc(sizeof(*caps), GFP_KERNEL))) + return -ENOMEM; + *pobject = &caps->object; + + nvkm_object_ctor(&gv100_disp_caps, oclass, &caps->object); + caps->disp = disp; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c index 9c658d632d37..47efb48d769a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c @@ -27,6 +27,7 @@ static const struct nv50_disp_root_func gv100_disp_root = { .user = { + {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, {{0,0,GV100_DISP_CURSOR }, gv100_disp_curs_new }, {{0,0,GV100_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, {{0,0,GV100_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index a1f942793f98..7070f5408d92 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -24,6 +24,9 @@ int nv50_disp_root_new_(const struct nv50_disp_root_func *, struct nvkm_disp *, const struct nvkm_oclass *, void *data, u32 size, struct nvkm_object **); +int gv100_disp_caps_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + extern const struct nvkm_disp_oclass nv50_disp_root_oclass; extern const struct nvkm_disp_oclass g84_disp_root_oclass; extern const struct nvkm_disp_oclass g94_disp_root_oclass; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c index 579a5d02308a..d8719d38b98a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c @@ -27,6 +27,7 @@ static const struct nv50_disp_root_func tu102_disp_root = { .user = { + {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, {{0,0,TU102_DISP_CURSOR }, gv100_disp_curs_new }, {{0,0,TU102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, {{0,0,TU102_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, -- cgit v1.2.3 From e3d8b08904694e9ccae5163d0bb7d35fa66e5bdc Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Tue, 3 Mar 2020 16:13:39 -0800 Subject: drm/nouveau/svm: map pages after migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When memory is migrated to the GPU, it is likely to be accessed by GPU code soon afterwards. Instead of waiting for a GPU fault, map the migrated memory into the GPU page tables with the same access permissions as the source CPU page table entries. This preserves copy on write semantics. Signed-off-by: Ralph Campbell Cc: Christoph Hellwig Cc: Jason Gunthorpe Cc: "Jérôme Glisse" Cc: Ben Skeggs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_dmem.c | 46 +++++++++++++++++--------- drivers/gpu/drm/nouveau/nouveau_dmem.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_svm.c | 59 +++++++++++++++++++++++++++++++++- drivers/gpu/drm/nouveau/nouveau_svm.h | 5 +++ 4 files changed, 95 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index ad89e09a0be3..a2ef8d562867 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -25,12 +25,14 @@ #include "nouveau_dma.h" #include "nouveau_mem.h" #include "nouveau_bo.h" +#include "nouveau_svm.h" #include #include #include #include #include +#include #include #include @@ -561,10 +563,11 @@ out_free: } static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm, - unsigned long src, dma_addr_t *dma_addr) + unsigned long src, dma_addr_t *dma_addr, u64 *pfn) { struct device *dev = drm->dev->dev; struct page *dpage, *spage; + unsigned long paddr; spage = migrate_pfn_to_page(src); if (!spage || !(src & MIGRATE_PFN_MIGRATE)) @@ -572,17 +575,21 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm, dpage = nouveau_dmem_page_alloc_locked(drm); if (!dpage) - return 0; + goto out; *dma_addr = dma_map_page(dev, spage, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, *dma_addr)) goto out_free_page; + paddr = nouveau_dmem_page_addr(dpage); if (drm->dmem->migrate.copy_func(drm, 1, NOUVEAU_APER_VRAM, - nouveau_dmem_page_addr(dpage), NOUVEAU_APER_HOST, - *dma_addr)) + paddr, NOUVEAU_APER_HOST, *dma_addr)) goto out_dma_unmap; + *pfn = NVIF_VMM_PFNMAP_V0_V | NVIF_VMM_PFNMAP_V0_VRAM | + ((paddr >> PAGE_SHIFT) << NVIF_VMM_PFNMAP_V0_ADDR_SHIFT); + if (src & MIGRATE_PFN_WRITE) + *pfn |= NVIF_VMM_PFNMAP_V0_W; return migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED; out_dma_unmap: @@ -590,18 +597,20 @@ out_dma_unmap: out_free_page: nouveau_dmem_page_free_locked(drm, dpage); out: + *pfn = NVIF_VMM_PFNMAP_V0_NONE; return 0; } static void nouveau_dmem_migrate_chunk(struct nouveau_drm *drm, - struct migrate_vma *args, dma_addr_t *dma_addrs) + struct nouveau_svmm *svmm, struct migrate_vma *args, + dma_addr_t *dma_addrs, u64 *pfns) { struct nouveau_fence *fence; unsigned long addr = args->start, nr_dma = 0, i; for (i = 0; addr < args->end; i++) { args->dst[i] = nouveau_dmem_migrate_copy_one(drm, args->src[i], - dma_addrs + nr_dma); + dma_addrs + nr_dma, pfns + i); if (args->dst[i]) nr_dma++; addr += PAGE_SIZE; @@ -610,20 +619,18 @@ static void nouveau_dmem_migrate_chunk(struct nouveau_drm *drm, nouveau_fence_new(drm->dmem->migrate.chan, false, &fence); migrate_vma_pages(args); nouveau_dmem_fence_done(&fence); + nouveau_pfns_map(svmm, args->vma->vm_mm, args->start, pfns, i); while (nr_dma--) { dma_unmap_page(drm->dev->dev, dma_addrs[nr_dma], PAGE_SIZE, DMA_BIDIRECTIONAL); } - /* - * FIXME optimization: update GPU page table to point to newly migrated - * memory. - */ migrate_vma_finalize(args); } int nouveau_dmem_migrate_vma(struct nouveau_drm *drm, + struct nouveau_svmm *svmm, struct vm_area_struct *vma, unsigned long start, unsigned long end) @@ -635,7 +642,8 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm, .vma = vma, .start = start, }; - unsigned long c, i; + unsigned long i; + u64 *pfns; int ret = -ENOMEM; args.src = kcalloc(max, sizeof(*args.src), GFP_KERNEL); @@ -649,19 +657,25 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm, if (!dma_addrs) goto out_free_dst; - for (i = 0; i < npages; i += c) { - c = min(SG_MAX_SINGLE_ALLOC, npages); - args.end = start + (c << PAGE_SHIFT); + pfns = nouveau_pfns_alloc(max); + if (!pfns) + goto out_free_dma; + + for (i = 0; i < npages; i += max) { + args.end = start + (max << PAGE_SHIFT); ret = migrate_vma_setup(&args); if (ret) - goto out_free_dma; + goto out_free_pfns; if (args.cpages) - nouveau_dmem_migrate_chunk(drm, &args, dma_addrs); + nouveau_dmem_migrate_chunk(drm, svmm, &args, dma_addrs, + pfns); args.start = args.end; } ret = 0; +out_free_pfns: + nouveau_pfns_free(pfns); out_free_dma: kfree(dma_addrs); out_free_dst: diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.h b/drivers/gpu/drm/nouveau/nouveau_dmem.h index 92394be5d649..3e03d9629a38 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.h +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.h @@ -25,6 +25,7 @@ struct drm_device; struct drm_file; struct nouveau_drm; +struct nouveau_svmm; struct hmm_range; #if IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM) @@ -34,6 +35,7 @@ void nouveau_dmem_suspend(struct nouveau_drm *); void nouveau_dmem_resume(struct nouveau_drm *); int nouveau_dmem_migrate_vma(struct nouveau_drm *drm, + struct nouveau_svmm *svmm, struct vm_area_struct *vma, unsigned long start, unsigned long end); diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index 645fedd77e21..fe89abf237a8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -70,6 +70,12 @@ struct nouveau_svm { #define SVM_DBG(s,f,a...) NV_DEBUG((s)->drm, "svm: "f"\n", ##a) #define SVM_ERR(s,f,a...) NV_WARN((s)->drm, "svm: "f"\n", ##a) +struct nouveau_pfnmap_args { + struct nvif_ioctl_v0 i; + struct nvif_ioctl_mthd_v0 m; + struct nvif_vmm_pfnmap_v0 p; +}; + struct nouveau_ivmm { struct nouveau_svmm *svmm; u64 inst; @@ -187,7 +193,8 @@ nouveau_svmm_bind(struct drm_device *dev, void *data, addr = max(addr, vma->vm_start); next = min(vma->vm_end, end); /* This is a best effort so we ignore errors */ - nouveau_dmem_migrate_vma(cli->drm, vma, addr, next); + nouveau_dmem_migrate_vma(cli->drm, cli->svm.svmm, vma, addr, + next); addr = next; } @@ -784,6 +791,56 @@ nouveau_svm_fault(struct nvif_notify *notify) return NVIF_NOTIFY_KEEP; } +static struct nouveau_pfnmap_args * +nouveau_pfns_to_args(void *pfns) +{ + return container_of(pfns, struct nouveau_pfnmap_args, p.phys); +} + +u64 * +nouveau_pfns_alloc(unsigned long npages) +{ + struct nouveau_pfnmap_args *args; + + args = kzalloc(struct_size(args, p.phys, npages), GFP_KERNEL); + if (!args) + return NULL; + + args->i.type = NVIF_IOCTL_V0_MTHD; + args->m.method = NVIF_VMM_V0_PFNMAP; + args->p.page = PAGE_SHIFT; + + return args->p.phys; +} + +void +nouveau_pfns_free(u64 *pfns) +{ + struct nouveau_pfnmap_args *args = nouveau_pfns_to_args(pfns); + + kfree(args); +} + +void +nouveau_pfns_map(struct nouveau_svmm *svmm, struct mm_struct *mm, + unsigned long addr, u64 *pfns, unsigned long npages) +{ + struct nouveau_pfnmap_args *args = nouveau_pfns_to_args(pfns); + int ret; + + args->p.addr = addr; + args->p.size = npages << PAGE_SHIFT; + + mutex_lock(&svmm->mutex); + + svmm->vmm->vmm.object.client->super = true; + ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, sizeof(*args) + + npages * sizeof(args->p.phys[0]), NULL); + svmm->vmm->vmm.object.client->super = false; + + mutex_unlock(&svmm->mutex); +} + static void nouveau_svm_fault_buffer_fini(struct nouveau_svm *svm, int id) { diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.h b/drivers/gpu/drm/nouveau/nouveau_svm.h index e839d8189461..f0fcd1b72e8b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.h +++ b/drivers/gpu/drm/nouveau/nouveau_svm.h @@ -18,6 +18,11 @@ void nouveau_svmm_fini(struct nouveau_svmm **); int nouveau_svmm_join(struct nouveau_svmm *, u64 inst); void nouveau_svmm_part(struct nouveau_svmm *, u64 inst); int nouveau_svmm_bind(struct drm_device *, void *, struct drm_file *); + +u64 *nouveau_pfns_alloc(unsigned long npages); +void nouveau_pfns_free(u64 *pfns); +void nouveau_pfns_map(struct nouveau_svmm *svmm, struct mm_struct *mm, + unsigned long addr, u64 *pfns, unsigned long npages); #else /* IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM) */ static inline void nouveau_svm_init(struct nouveau_drm *drm) {} static inline void nouveau_svm_fini(struct nouveau_drm *drm) {} -- cgit v1.2.3 From cf0f64ff4f28b4ed0cae9a3a907eda95cbe69cfe Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 29 Feb 2020 00:53:07 +0000 Subject: drm/nouveau/core/memory: remove redundant assignments to variable ret The variable ret is being initialized with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/core/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c index 4cc186262d34..38130ef272d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -140,7 +140,7 @@ nvkm_memory_new(struct nvkm_device *device, enum nvkm_memory_target target, { struct nvkm_instmem *imem = device->imem; struct nvkm_memory *memory; - int ret = -ENOSYS; + int ret; if (unlikely(target != NVKM_MEM_TARGET_INST || !imem)) return -ENOSYS; -- cgit v1.2.3 From 75a708918a92e30765d793b78b323efae12ef2b0 Mon Sep 17 00:00:00 2001 From: Zou Wei Date: Tue, 21 Apr 2020 20:37:31 +0800 Subject: drm/nouveau/acr: Use kmemdup instead of kmalloc and memcpy Fixes coccicheck warning: drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c:103:23-30: WARNING opportunity for kmemdup drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c:113:22-29: WARNING opportunity for kmemdup Fixes: 22dcda45a3d1 ("drm/nouveau/acr: implement new subdev to replace "secure boot"") Reported-by: Hulk Robot Signed-off-by: Zou Wei Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c index aecce2dac558..667fa016496e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c @@ -100,25 +100,21 @@ nvkm_acr_hsfw_load_image(struct nvkm_acr *acr, const char *name, int ver, hsfw->data_size = lhdr->data_size; hsfw->sig.prod.size = fwhdr->sig_prod_size; - hsfw->sig.prod.data = kmalloc(hsfw->sig.prod.size, GFP_KERNEL); + hsfw->sig.prod.data = kmemdup(fw->data + fwhdr->sig_prod_offset + sig, + hsfw->sig.prod.size, GFP_KERNEL); if (!hsfw->sig.prod.data) { ret = -ENOMEM; goto done; } - memcpy(hsfw->sig.prod.data, fw->data + fwhdr->sig_prod_offset + sig, - hsfw->sig.prod.size); - hsfw->sig.dbg.size = fwhdr->sig_dbg_size; - hsfw->sig.dbg.data = kmalloc(hsfw->sig.dbg.size, GFP_KERNEL); + hsfw->sig.dbg.data = kmemdup(fw->data + fwhdr->sig_dbg_offset + sig, + hsfw->sig.dbg.size, GFP_KERNEL); if (!hsfw->sig.dbg.data) { ret = -ENOMEM; goto done; } - memcpy(hsfw->sig.dbg.data, fw->data + fwhdr->sig_dbg_offset + sig, - hsfw->sig.dbg.size); - hsfw->sig.patch_loc = loc; done: nvkm_firmware_put(fw); -- cgit v1.2.3 From ccfc2d5cdb02459ac8878125dd5e1a8367e8bd79 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 23 Apr 2020 14:23:58 +0800 Subject: drm/nouveau: Use generic helper to check _PR3 presence Replace nouveau_pr3_present() in favor of a more generic one, pci_pr3_present(). Also the presence of upstream bridge _PR3 doesn't need to go hand in hand with device's _DSM, so check _PR3 before _DSM. Signed-off-by: Kai-Heng Feng Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 44 ++++++++-------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 65440ec9b6f2..69a84d0197d0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -211,37 +211,6 @@ static const struct vga_switcheroo_handler nouveau_dsm_handler = { .get_client_id = nouveau_dsm_get_client_id, }; -/* - * Firmware supporting Windows 8 or later do not use _DSM to put the device into - * D3cold, they instead rely on disabling power resources on the parent. - */ -static bool nouveau_pr3_present(struct pci_dev *pdev) -{ - struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); - struct acpi_device *parent_adev; - - if (!parent_pdev) - return false; - - if (!parent_pdev->bridge_d3) { - /* - * Parent PCI bridge is currently not power managed. - * Since userspace can change these afterwards to be on - * the safe side we stick with _DSM and prevent usage of - * _PR3 from the bridge. - */ - pci_d3cold_disable(pdev); - return false; - } - - parent_adev = ACPI_COMPANION(&parent_pdev->dev); - if (!parent_adev) - return false; - - return parent_adev->power.flags.power_resources && - acpi_has_method(parent_adev->handle, "_PR3"); -} - static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out, bool *has_mux, bool *has_opt, bool *has_opt_flags, bool *has_pr3) @@ -249,6 +218,16 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out acpi_handle dhandle; bool supports_mux; int optimus_funcs; + struct pci_dev *parent_pdev; + + *has_pr3 = false; + parent_pdev = pci_upstream_bridge(pdev); + if (parent_pdev) { + if (parent_pdev->bridge_d3) + *has_pr3 = pci_pr3_present(parent_pdev); + else + pci_d3cold_disable(pdev); + } dhandle = ACPI_HANDLE(&pdev->dev); if (!dhandle) @@ -269,7 +248,6 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out *has_mux = supports_mux; *has_opt = !!optimus_funcs; *has_opt_flags = optimus_funcs & (1 << NOUVEAU_DSM_OPTIMUS_FLAGS); - *has_pr3 = false; if (optimus_funcs) { uint32_t result; @@ -279,8 +257,6 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out (result & OPTIMUS_ENABLED) ? "enabled" : "disabled", (result & OPTIMUS_DYNAMIC_PWR_CAP) ? "dynamic power, " : "", (result & OPTIMUS_HDA_CODEC_MASK) ? "hda bios codec supported" : ""); - - *has_pr3 = nouveau_pr3_present(pdev); } } -- cgit v1.2.3 From 94db9a3b0f6d1e87e315515744db46c6c86680d0 Mon Sep 17 00:00:00 2001 From: Zheng Bin Date: Fri, 24 Apr 2020 15:36:01 +0800 Subject: drm/nouveau/mmu: Remove unneeded semicolon Fixes coccicheck warning: drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h:307:2-3: Unneeded semicolon drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c:583:2-3: Unneeded semicolon Reported-by: Hulk Robot Signed-off-by: Zheng Bin Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 41640e0584ac..199f94e15c5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -580,7 +580,7 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, it.pte[it.lvl]++; } } - }; + } nvkm_vmm_flush(&it); return ~0ULL; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 5e55ecbd8005..d3f8f916d0db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -304,7 +304,7 @@ int tu102_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, FILL(VMM, PT, PTEI, _ptes, MAP, _addr); \ PTEI += _ptes; \ PTEN -= _ptes; \ - }; \ + } \ nvkm_done((PT)->memory); \ } while(0) -- cgit v1.2.3 From 24d5ff40a732633dceab68c6559ba723784f4a68 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Tue, 28 Apr 2020 18:54:02 +0200 Subject: drm/nouveau/device: rework mmio mapping code to get rid of second map Fixes warnings on GPUs with smaller a smaller mmio region like vGPUs. Signed-off-by: Karol Herbst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 8ebbe1656008..37589f36546d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2935,7 +2935,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, struct nvkm_subdev *subdev; u64 mmio_base, mmio_size; u32 boot0, strap; - void __iomem *map; + void __iomem *map = NULL; int ret = -EEXIST, i; unsigned chipset; @@ -2961,12 +2961,17 @@ nvkm_device_ctor(const struct nvkm_device_func *func, mmio_base = device->func->resource_addr(device, 0); mmio_size = device->func->resource_size(device, 0); - /* identify the chipset, and determine classes of subdev/engines */ - if (detect) { - map = ioremap(mmio_base, 0x102000); - if (ret = -ENOMEM, map == NULL) + if (detect || mmio) { + map = ioremap(mmio_base, mmio_size); + if (map == NULL) { + nvdev_error(device, "unable to map PRI\n"); + ret = -ENOMEM; goto done; + } + } + /* identify the chipset, and determine classes of subdev/engines */ + if (detect) { /* switch mmio to cpu's native endianness */ #ifndef __BIG_ENDIAN if (ioread32_native(map + 0x000004) != 0x00000000) { @@ -2980,7 +2985,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func, /* read boot0 and strapping information */ boot0 = ioread32_native(map + 0x000000); strap = ioread32_native(map + 0x101000); - iounmap(map); /* chipset can be overridden for devel/testing purposes */ chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); @@ -3159,12 +3163,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, device->name = device->chip->name; if (mmio) { - device->pri = ioremap(mmio_base, mmio_size); - if (!device->pri) { - nvdev_error(device, "unable to map PRI\n"); - ret = -ENOMEM; - goto done; - } + device->pri = map; } mutex_init(&device->mutex); @@ -3254,6 +3253,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, ret = 0; done: + if (map && (!mmio || ret)) { + device->pri = NULL; + iounmap(map); + } mutex_unlock(&nv_devices_mutex); return ret; } -- cgit v1.2.3 From 51c05340e407b14b7d8ca5c6ad7027f269fc617b Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Tue, 28 Apr 2020 18:54:03 +0200 Subject: drm/nouveau/device: detect if changing endianness failed v2: relax the checks a little Signed-off-by: Karol Herbst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 26 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 37589f36546d..c732074bf790 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2924,6 +2924,20 @@ nvkm_device_del(struct nvkm_device **pdevice) } } +static inline bool +nvkm_device_endianness(void __iomem *pri) +{ + u32 boot1 = ioread32_native(pri + 0x000004) & 0x01000001; +#ifdef __BIG_ENDIAN + if (!boot1) + return false; +#else + if (boot1) + return false; +#endif + return true; +} + int nvkm_device_ctor(const struct nvkm_device_func *func, const struct nvkm_device_quirk *quirk, @@ -2973,13 +2987,15 @@ nvkm_device_ctor(const struct nvkm_device_func *func, /* identify the chipset, and determine classes of subdev/engines */ if (detect) { /* switch mmio to cpu's native endianness */ -#ifndef __BIG_ENDIAN - if (ioread32_native(map + 0x000004) != 0x00000000) { -#else - if (ioread32_native(map + 0x000004) == 0x00000000) { -#endif + if (!nvkm_device_endianness(map)) { iowrite32_native(0x01000001, map + 0x000004); ioread32_native(map); + if (!nvkm_device_endianness(map)) { + nvdev_error(device, + "GPU not supported on big-endian\n"); + ret = -ENOSYS; + goto done; + } } /* read boot0 and strapping information */ -- cgit v1.2.3 From 2924779bcaead13828ce3101e573eb5663900b92 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Tue, 28 Apr 2020 18:54:04 +0200 Subject: drm/nouveau/device: detect vGPUs Using ENODEV as this prevents probe failed errors in dmesg. v2: move check further down Signed-off-by: Karol Herbst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index c732074bf790..f977dddcd809 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2948,7 +2948,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, { struct nvkm_subdev *subdev; u64 mmio_base, mmio_size; - u32 boot0, strap; + u32 boot0, boot1, strap; void __iomem *map = NULL; int ret = -EEXIST, i; unsigned chipset; @@ -2998,9 +2998,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, } } - /* read boot0 and strapping information */ boot0 = ioread32_native(map + 0x000000); - strap = ioread32_native(map + 0x101000); /* chipset can be overridden for devel/testing purposes */ chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); @@ -3158,6 +3156,17 @@ nvkm_device_ctor(const struct nvkm_device_func *func, nvdev_info(device, "NVIDIA %s (%08x)\n", device->chip->name, boot0); + /* vGPU detection */ + boot1 = ioread32_native(map + 0x000004); + if (device->card_type >= TU100 && (boot1 & 0x00030000)) { + nvdev_info(device, "vGPUs are not supported\n"); + ret = -ENODEV; + goto done; + } + + /* read strapping information */ + strap = ioread32_native(map + 0x101000); + /* determine frequency of timing crystal */ if ( device->card_type <= NV_10 || device->chipset < 0x17 || (device->chipset >= 0x20 && device->chipset < 0x25)) -- cgit v1.2.3 From 0f85bbb6ae517d9a4308527188afe35c2012bbc9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 30 Apr 2020 14:08:53 +1000 Subject: drm/nouveau/device: use regular PRI accessors in chipset detection Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 31 ++++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index f977dddcd809..5b90c2a1bf3d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2925,9 +2925,9 @@ nvkm_device_del(struct nvkm_device **pdevice) } static inline bool -nvkm_device_endianness(void __iomem *pri) +nvkm_device_endianness(struct nvkm_device *device) { - u32 boot1 = ioread32_native(pri + 0x000004) & 0x01000001; + u32 boot1 = nvkm_rd32(device, 0x000004) & 0x01000001; #ifdef __BIG_ENDIAN if (!boot1) return false; @@ -2949,7 +2949,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func, struct nvkm_subdev *subdev; u64 mmio_base, mmio_size; u32 boot0, boot1, strap; - void __iomem *map = NULL; int ret = -EEXIST, i; unsigned chipset; @@ -2976,8 +2975,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func, mmio_size = device->func->resource_size(device, 0); if (detect || mmio) { - map = ioremap(mmio_base, mmio_size); - if (map == NULL) { + device->pri = ioremap(mmio_base, mmio_size); + if (device->pri == NULL) { nvdev_error(device, "unable to map PRI\n"); ret = -ENOMEM; goto done; @@ -2987,10 +2986,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, /* identify the chipset, and determine classes of subdev/engines */ if (detect) { /* switch mmio to cpu's native endianness */ - if (!nvkm_device_endianness(map)) { - iowrite32_native(0x01000001, map + 0x000004); - ioread32_native(map); - if (!nvkm_device_endianness(map)) { + if (!nvkm_device_endianness(device)) { + nvkm_wr32(device, 0x000004, 0x01000001); + nvkm_rd32(device, 0x000000); + if (!nvkm_device_endianness(device)) { nvdev_error(device, "GPU not supported on big-endian\n"); ret = -ENOSYS; @@ -2998,7 +2997,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, } } - boot0 = ioread32_native(map + 0x000000); + boot0 = nvkm_rd32(device, 0x000000); /* chipset can be overridden for devel/testing purposes */ chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); @@ -3157,7 +3156,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, device->chip->name, boot0); /* vGPU detection */ - boot1 = ioread32_native(map + 0x000004); + boot1 = nvkm_rd32(device, 0x0000004); if (device->card_type >= TU100 && (boot1 & 0x00030000)) { nvdev_info(device, "vGPUs are not supported\n"); ret = -ENODEV; @@ -3165,7 +3164,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, } /* read strapping information */ - strap = ioread32_native(map + 0x101000); + strap = nvkm_rd32(device, 0x101000); /* determine frequency of timing crystal */ if ( device->card_type <= NV_10 || device->chipset < 0x17 || @@ -3187,10 +3186,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func, if (!device->name) device->name = device->chip->name; - if (mmio) { - device->pri = map; - } - mutex_init(&device->mutex); for (i = 0; i < NVKM_SUBDEV_NR; i++) { @@ -3278,9 +3273,9 @@ nvkm_device_ctor(const struct nvkm_device_func *func, ret = 0; done: - if (map && (!mmio || ret)) { + if (device->pri && (!mmio || ret)) { + iounmap(device->pri); device->pri = NULL; - iounmap(map); } mutex_unlock(&nv_devices_mutex); return ret; -- cgit v1.2.3 From 61a41097e4bd4bf5d4abf3b3b58d5bf0856ce144 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Apr 2020 09:54:28 +0200 Subject: drm/nouveau/kms: Fix regression by audio component transition Since the commit 742db30c4ee6 ("drm/nouveau: Add HD-audio component notifier support"), the nouveau driver notifies and pokes the HD-audio HPD and ELD via audio component, but this seems broken. The culprit is the naive assumption that crtc->index corresponds to the HDA pin. Actually this rather corresponds to the MST dev_id (alias "pipe" in the audio component framework) while the actual port number is given from the output ior id number. This patch corrects the assignment of port and dev_id arguments in the audio component ops to recover from the HDMI/DP audio regression. Fixes: 742db30c4ee6 ("drm/nouveau: Add HD-audio component notifier support") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207223 Cc: Signed-off-by: Takashi Iwai Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 8a79f06e9e26..1296a0ab1546 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -482,15 +482,16 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) * audio component binding for ELD notification */ static void -nv50_audio_component_eld_notify(struct drm_audio_component *acomp, int port) +nv50_audio_component_eld_notify(struct drm_audio_component *acomp, int port, + int dev_id) { if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, - port, -1); + port, dev_id); } static int -nv50_audio_component_get_eld(struct device *kdev, int port, int pipe, +nv50_audio_component_get_eld(struct device *kdev, int port, int dev_id, bool *enabled, unsigned char *buf, int max_bytes) { struct drm_device *drm_dev = dev_get_drvdata(kdev); @@ -506,7 +507,8 @@ nv50_audio_component_get_eld(struct device *kdev, int port, int pipe, nv_encoder = nouveau_encoder(encoder); nv_connector = nouveau_encoder_connector_get(nv_encoder); nv_crtc = nouveau_crtc(encoder->crtc); - if (!nv_connector || !nv_crtc || nv_crtc->index != port) + if (!nv_connector || !nv_crtc || nv_encoder->or != port || + nv_crtc->index != dev_id) continue; *enabled = drm_detect_monitor_audio(nv_connector->edid); if (*enabled) { @@ -600,7 +602,8 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); - nv50_audio_component_eld_notify(drm->audio.component, nv_crtc->index); + nv50_audio_component_eld_notify(drm->audio.component, nv_encoder->or, + nv_crtc->index); } static void @@ -634,7 +637,8 @@ nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) nvif_mthd(&disp->disp->object, 0, &args, sizeof(args.base) + drm_eld_size(args.data)); - nv50_audio_component_eld_notify(drm->audio.component, nv_crtc->index); + nv50_audio_component_eld_notify(drm->audio.component, nv_encoder->or, + nv_crtc->index); } /****************************************************************************** -- cgit v1.2.3 From 18d8cf93093e207b22770f165120f2115c83f73a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 May 2020 14:40:45 +1000 Subject: drm/nouveau/disp/nv50-: increase timeout on pio channel free() polling Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index 8c5cf096f69b..658a200ab616 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -32,7 +32,7 @@ bool curs507a_space(struct nv50_wndw *wndw) { - nvif_msec(&nouveau_drm(wndw->plane.dev)->client.device, 2, + nvif_msec(&nouveau_drm(wndw->plane.dev)->client.device, 100, if (nvif_rd32(&wndw->wimm.base.user, 0x0008) >= 4) return true; ); -- cgit v1.2.3 From 1404e56a49f0dd6f50ded3290d37b795e3cbd6e9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 May 2020 14:40:52 +1000 Subject: drm/nouveau/disp/hda/gt215-: pass head to nvkm_ior.hda.eld() We're going to use the bound head to select HDA device entry. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c index 0fa0ec0a1de0..1080ba6ecd64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c @@ -24,7 +24,7 @@ #include "ior.h" void -gf119_hda_eld(struct nvkm_ior *ior, u8 *data, u8 size) +gf119_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size) { struct nvkm_device *device = ior->disp->engine.subdev.device; const u32 soff = 0x030 * ior->id; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c index 4509d2ba880e..0d1b81fe1093 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c @@ -24,7 +24,7 @@ #include "ior.h" void -gt215_hda_eld(struct nvkm_ior *ior, u8 *data, u8 size) +gt215_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size) { struct nvkm_device *device = ior->disp->engine.subdev.device; const u32 soff = ior->id * 0x800; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index 009d3a8b7a50..c60acf71831e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -87,7 +87,7 @@ struct nvkm_ior_func { struct { void (*hpd)(struct nvkm_ior *, int head, bool present); - void (*eld)(struct nvkm_ior *, u8 *data, u8 size); + void (*eld)(struct nvkm_ior *, int head, u8 *data, u8 size); } hda; }; @@ -158,10 +158,10 @@ void gv100_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); void gm200_hdmi_scdc(struct nvkm_ior *, int, u8); void gt215_hda_hpd(struct nvkm_ior *, int, bool); -void gt215_hda_eld(struct nvkm_ior *, u8 *, u8); +void gt215_hda_eld(struct nvkm_ior *, int, u8 *, u8); void gf119_hda_hpd(struct nvkm_ior *, int, bool); -void gf119_hda_eld(struct nvkm_ior *, u8 *, u8); +void gf119_hda_eld(struct nvkm_ior *, int, u8 *, u8); #define IOR_MSG(i,l,f,a...) do { \ struct nvkm_ior *_ior = (i); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 5f758948d6e1..a7672ef17d3b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -155,7 +155,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) if (outp->info.type == DCB_OUTPUT_DP) ior->func->dp.audio(ior, hidx, true); ior->func->hda.hpd(ior, hidx, true); - ior->func->hda.eld(ior, data, size); + ior->func->hda.eld(ior, hidx, data, size); } else { if (outp->info.type == DCB_OUTPUT_DP) ior->func->dp.audio(ior, hidx, false); -- cgit v1.2.3 From d4115d17cd91c137b713b0e1482613093d6007c1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 May 2020 14:40:56 +1000 Subject: drm/nouveau/disp/hda/gf119-: add HAL for programming device entry in SF Register has moved on GV100. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c | 11 +++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c | 1 + 8 files changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c index 1080ba6ecd64..8a0ec7db5145 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c @@ -23,6 +23,14 @@ */ #include "ior.h" +void +gf119_hda_device_entry(struct nvkm_ior *ior, int head) +{ + struct nvkm_device *device = ior->disp->engine.subdev.device; + const u32 hoff = 0x800 * head; + nvkm_mask(device, 0x616548 + hoff, 0x00000070, 0x00000000); +} + void gf119_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size) { @@ -41,11 +49,10 @@ void gf119_hda_hpd(struct nvkm_ior *ior, int head, bool present) { struct nvkm_device *device = ior->disp->engine.subdev.device; - const u32 hoff = 0x800 * head; u32 data = 0x80000000; u32 mask = 0x80000001; if (present) { - nvkm_mask(device, 0x616548 + hoff, 0x00000070, 0x00000000); + ior->func->hda.device_entry(ior, head); data |= 0x00000001; } else { mask |= 0x00000002; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index c60acf71831e..eb1155e47ecd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -88,6 +88,7 @@ struct nvkm_ior_func { struct { void (*hpd)(struct nvkm_ior *, int head, bool present); void (*eld)(struct nvkm_ior *, int head, u8 *data, u8 size); + void (*device_entry)(struct nvkm_ior *, int head); } hda; }; @@ -162,6 +163,7 @@ void gt215_hda_eld(struct nvkm_ior *, int, u8 *, u8); void gf119_hda_hpd(struct nvkm_ior *, int, bool); void gf119_hda_eld(struct nvkm_ior *, int, u8 *, u8); +void gf119_hda_device_entry(struct nvkm_ior *, int); #define IOR_MSG(i,l,f,a...) do { \ struct nvkm_ior *_ior = (i); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index 456a5a143522..3b3643fb1019 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c @@ -177,6 +177,7 @@ gf119_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c index b94090edaebf..0c0925680790 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c @@ -43,6 +43,7 @@ gk104_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c index e6965dec09c9..38045c92197f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c @@ -57,6 +57,7 @@ gm107_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index 384f82652bec..cf2075db742a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c @@ -115,6 +115,7 @@ gm200_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c index b0597ff9a714..565cfbc65550 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c @@ -103,6 +103,7 @@ gv100_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c index 4d5f3791ea7b..b16ecea098c7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c @@ -88,6 +88,7 @@ tu102_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; -- cgit v1.2.3 From 7ec60c044069ac40fd0f28e2469b9dde9ea6e4ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 May 2020 14:40:58 +1000 Subject: drm/nouveau/disp/hda/gf119-: select HDA device entry based on bound head Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c index 8a0ec7db5145..19d2d58344e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c @@ -28,14 +28,14 @@ gf119_hda_device_entry(struct nvkm_ior *ior, int head) { struct nvkm_device *device = ior->disp->engine.subdev.device; const u32 hoff = 0x800 * head; - nvkm_mask(device, 0x616548 + hoff, 0x00000070, 0x00000000); + nvkm_mask(device, 0x616548 + hoff, 0x00000070, head << 4); } void gf119_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size) { struct nvkm_device *device = ior->disp->engine.subdev.device; - const u32 soff = 0x030 * ior->id; + const u32 soff = 0x030 * ior->id + (head * 0x04); int i; for (i = 0; i < size; i++) @@ -49,6 +49,7 @@ void gf119_hda_hpd(struct nvkm_ior *ior, int head, bool present) { struct nvkm_device *device = ior->disp->engine.subdev.device; + const u32 soff = 0x030 * ior->id + (head * 0x04); u32 data = 0x80000000; u32 mask = 0x80000001; if (present) { @@ -57,5 +58,5 @@ gf119_hda_hpd(struct nvkm_ior *ior, int head, bool present) } else { mask |= 0x00000002; } - nvkm_mask(device, 0x10ec10 + ior->id * 0x030, mask, data); + nvkm_mask(device, 0x10ec10 + soff, mask, data); } -- cgit v1.2.3 From 0435d7c69271a2ed93984f68af452e584aa43e4d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 May 2020 14:41:01 +1000 Subject: drm/nouveau/disp/hda/gv100-: NV_PDISP_SF_AUDIO_CNTRL0 register moved Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c | 30 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 2 ++ .../gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/sortu102.c | 2 +- 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index f7af648e0c17..571687ba85b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -47,6 +47,7 @@ nvkm-y += nvkm/engine/disp/dp.o nvkm-y += nvkm/engine/disp/hdagt215.o nvkm-y += nvkm/engine/disp/hdagf119.o +nvkm-y += nvkm/engine/disp/hdagv100.o nvkm-y += nvkm/engine/disp/hdmi.o nvkm-y += nvkm/engine/disp/hdmig84.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c new file mode 100644 index 000000000000..57d374ecfeef --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c @@ -0,0 +1,30 @@ +/* + * Copyright 2020 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. + */ +#include "ior.h" + +void +gv100_hda_device_entry(struct nvkm_ior *ior, int head) +{ + struct nvkm_device *device = ior->disp->engine.subdev.device; + const u32 hoff = 0x800 * head; + nvkm_mask(device, 0x616528 + hoff, 0x00000070, head << 4); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index eb1155e47ecd..c1d7a36e4d3c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -165,6 +165,8 @@ void gf119_hda_hpd(struct nvkm_ior *, int, bool); void gf119_hda_eld(struct nvkm_ior *, int, u8 *, u8); void gf119_hda_device_entry(struct nvkm_ior *, int); +void gv100_hda_device_entry(struct nvkm_ior *, int); + #define IOR_MSG(i,l,f,a...) do { \ struct nvkm_ior *_ior = (i); \ nvkm_##l(&_ior->disp->engine.subdev, "%s: "f"\n", _ior->name, ##a); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c index 565cfbc65550..d11a0dff10c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c @@ -103,7 +103,7 @@ gv100_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, - .device_entry = gf119_hda_device_entry, + .device_entry = gv100_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c index b16ecea098c7..fa6d74251237 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c @@ -88,7 +88,7 @@ tu102_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, - .device_entry = gf119_hda_device_entry, + .device_entry = gv100_hda_device_entry, }, }; -- cgit v1.2.3 From fa1232ea84515533a8c52f9b88151d2bef4c913d Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 11 May 2020 18:41:23 -0400 Subject: drm/nouveau/kms/nv50-: Initialize core channel in nouveau_display_create() We'll need the core channel initialized and ready by the time that we start creating modesetting objects, so that we can call the NV507D_GET_CAPABILITIES method to make the hardware expose it's modesetting capabilities for later probing. So, when loading the driver prepare the core channel from within nouveau_display_create(). Everywhere else, we initialize the core channel during resume. Signed-off-by: Lyude Paul Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 1296a0ab1546..d5488c85eb43 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2373,7 +2373,8 @@ nv50_display_init(struct drm_device *dev, bool resume, bool runtime) struct drm_encoder *encoder; struct drm_plane *plane; - core->func->init(core); + if (resume || runtime) + core->func->init(core); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { @@ -2460,6 +2461,8 @@ nv50_display_create(struct drm_device *dev) if (ret) goto out; + disp->core->func->init(disp->core); + /* Assign the correct format modifiers */ if (disp->disp->object.oclass >= TU102_DISP) nouveau_display(dev)->format_modifiers = wndwc57e_modifiers; -- cgit v1.2.3 From 4a2cb4181b077cf028c955d1f61d9244b2e93263 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 11 May 2020 18:41:24 -0400 Subject: drm/nouveau/kms/nv50-: Probe SOR and PIOR caps for DP interlacing support Right now, we make the mistake of allowing interlacing on all connectors. Nvidia hardware does not always support interlacing with DP though, so we need to make sure that we don't allow interlaced modes to be set in such situations as otherwise we'll end up accidentally hanging the display HW. This fixes some hangs with Turing, which would be caused by attempting to set an interlaced mode on hardware that doesn't support it. This patch likely fixes other hardware hanging in the same way as well. Note that we say we probe PIOR caps, but they don't actually have any interlacing caps. So, the get_caps() function for PIORs just sets interlacing support to true. Changes since v1: * Actually probe caps correctly this time, both on EVO and NVDisplay. Changes since v2: * Fix probing for < GF119 * Use vfunc table, in prep for adding more caps in the future. Signed-off-by: Lyude Paul Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/core.h | 7 +++++++ drivers/gpu/drm/nouveau/dispnv50/core507d.c | 15 +++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/core827d.c | 1 + drivers/gpu/drm/nouveau/dispnv50/core907d.c | 1 + drivers/gpu/drm/nouveau/dispnv50/core917d.c | 1 + drivers/gpu/drm/nouveau/dispnv50/corec37d.c | 26 ++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/corec57d.c | 1 + drivers/gpu/drm/nouveau/dispnv50/disp.c | 19 +++++++++++++++++-- drivers/gpu/drm/nouveau/dispnv50/disp.h | 1 + drivers/gpu/drm/nouveau/dispnv50/pior507d.c | 8 ++++++++ drivers/gpu/drm/nouveau/dispnv50/sor507d.c | 7 +++++++ drivers/gpu/drm/nouveau/dispnv50/sor907d.c | 11 +++++++++++ drivers/gpu/drm/nouveau/dispnv50/sorc37d.c | 9 +++++++++ drivers/gpu/drm/nouveau/nouveau_connector.c | 10 +++++++++- drivers/gpu/drm/nouveau/nouveau_encoder.h | 4 ++++ 15 files changed, 118 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h index ff94f3f6f264..99157dc94d23 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.h +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -2,6 +2,7 @@ #define __NV50_KMS_CORE_H__ #include "disp.h" #include "atom.h" +#include struct nv50_core { const struct nv50_core_func *func; @@ -15,6 +16,7 @@ void nv50_core_del(struct nv50_core **); struct nv50_core_func { void (*init)(struct nv50_core *); void (*ntfy_init)(struct nouveau_bo *, u32 offset); + int (*caps_init)(struct nouveau_drm *, struct nv50_disp *); int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset, struct nvif_device *); void (*update)(struct nv50_core *, u32 *interlock, bool ntfy); @@ -27,6 +29,9 @@ struct nv50_core_func { const struct nv50_outp_func { void (*ctrl)(struct nv50_core *, int or, u32 ctrl, struct nv50_head_atom *); + /* XXX: Only used by SORs and PIORs for now */ + void (*get_caps)(struct nv50_disp *, + struct nouveau_encoder *, int or); } *dac, *pior, *sor; }; @@ -35,6 +40,7 @@ int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32, struct nv50_core **); void core507d_init(struct nv50_core *); void core507d_ntfy_init(struct nouveau_bo *, u32); +int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *); int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); void core507d_update(struct nv50_core *, u32 *, bool); @@ -51,6 +57,7 @@ extern const struct nv50_outp_func sor907d; int core917d_new(struct nouveau_drm *, s32, struct nv50_core **); int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **); +int corec37d_caps_init(struct nouveau_drm *, struct nv50_disp *); int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); void corec37d_update(struct nv50_core *, u32 *, bool); void corec37d_wndw_owner(struct nv50_core *); diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index c5152c39c684..e341f572c269 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -62,6 +62,20 @@ core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) nouveau_bo_wr32(bo, offset / 4, 0x00000000); } +int +core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) +{ + u32 *push = evo_wait(&disp->core->chan, 2); + + if (push) { + evo_mthd(push, 0x008c, 1); + evo_data(push, 0x0); + evo_kick(push, &disp->core->chan); + } + + return 0; +} + void core507d_init(struct nv50_core *core) { @@ -77,6 +91,7 @@ static const struct nv50_core_func core507d = { .init = core507d_init, .ntfy_init = core507d_ntfy_init, + .caps_init = core507d_caps_init, .ntfy_wait_done = core507d_ntfy_wait_done, .update = core507d_update, .head = &head507d, diff --git a/drivers/gpu/drm/nouveau/dispnv50/core827d.c b/drivers/gpu/drm/nouveau/dispnv50/core827d.c index 6123a068f836..2e0c1c536afe 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core827d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core827d.c @@ -26,6 +26,7 @@ static const struct nv50_core_func core827d = { .init = core507d_init, .ntfy_init = core507d_ntfy_init, + .caps_init = core507d_caps_init, .ntfy_wait_done = core507d_ntfy_wait_done, .update = core507d_update, .head = &head827d, diff --git a/drivers/gpu/drm/nouveau/dispnv50/core907d.c b/drivers/gpu/drm/nouveau/dispnv50/core907d.c index ef822f813435..271629832629 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core907d.c @@ -26,6 +26,7 @@ static const struct nv50_core_func core907d = { .init = core507d_init, .ntfy_init = core507d_ntfy_init, + .caps_init = core507d_caps_init, .ntfy_wait_done = core507d_ntfy_wait_done, .update = core507d_update, .head = &head907d, diff --git a/drivers/gpu/drm/nouveau/dispnv50/core917d.c b/drivers/gpu/drm/nouveau/dispnv50/core917d.c index 392338df5bfd..5cc072d4c30f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core917d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core917d.c @@ -26,6 +26,7 @@ static const struct nv50_core_func core917d = { .init = core507d_init, .ntfy_init = core507d_ntfy_init, + .caps_init = core507d_caps_init, .ntfy_wait_done = core507d_ntfy_wait_done, .update = core507d_update, .head = &head917d, diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c index c03cb987856b..e0c8811fb8e4 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c @@ -22,6 +22,7 @@ #include "core.h" #include "head.h" +#include #include #include @@ -87,6 +88,30 @@ corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset) nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000); } +int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) +{ + int ret; + + ret = nvif_object_init(&disp->disp->object, 0, GV100_DISP_CAPS, + NULL, 0, &disp->caps); + if (ret) { + NV_ERROR(drm, + "Failed to init notifier caps region: %d\n", + ret); + return ret; + } + + ret = nvif_object_map(&disp->caps, NULL, 0); + if (ret) { + NV_ERROR(drm, + "Failed to map notifier caps region: %d\n", + ret); + return ret; + } + + return 0; +} + static void corec37d_init(struct nv50_core *core) { @@ -111,6 +136,7 @@ static const struct nv50_core_func corec37d = { .init = corec37d_init, .ntfy_init = corec37d_ntfy_init, + .caps_init = corec37d_caps_init, .ntfy_wait_done = corec37d_ntfy_wait_done, .update = corec37d_update, .wndw.owner = corec37d_wndw_owner, diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec57d.c b/drivers/gpu/drm/nouveau/dispnv50/corec57d.c index 147adcd60937..10ba9e9e4ae6 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/corec57d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/corec57d.c @@ -46,6 +46,7 @@ static const struct nv50_core_func corec57d = { .init = corec57d_init, .ntfy_init = corec37d_ntfy_init, + .caps_init = corec37d_caps_init, .ntfy_wait_done = corec37d_ntfy_wait_done, .update = corec37d_update, .wndw.owner = corec37d_wndw_owner, diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index d5488c85eb43..e6a93fdfc6a2 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1663,6 +1663,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) struct nvkm_i2c *i2c = nvxx_i2c(&drm->client.device); struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; + struct nv50_disp *disp = nv50_disp(connector->dev); int type, ret; switch (dcbe->type) { @@ -1689,10 +1690,12 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) drm_connector_attach_encoder(connector, encoder); + disp->core->func->sor->get_caps(disp, nv_encoder, ffs(dcbe->or) - 1); + if (dcbe->type == DCB_OUTPUT_DP) { - struct nv50_disp *disp = nv50_disp(encoder->dev); struct nvkm_i2c_aux *aux = nvkm_i2c_aux_find(i2c, dcbe->i2c_index); + if (aux) { if (disp->disp->object.oclass < GF110_DISP) { /* HW has no support for address-only @@ -1805,7 +1808,9 @@ nv50_pior_func = { static int nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) { - struct nouveau_drm *drm = nouveau_drm(connector->dev); + struct drm_device *dev = connector->dev; + struct nouveau_drm *drm = nouveau_drm(dev); + struct nv50_disp *disp = nv50_disp(dev); struct nvkm_i2c *i2c = nvxx_i2c(&drm->client.device); struct nvkm_i2c_bus *bus = NULL; struct nvkm_i2c_aux *aux = NULL; @@ -1844,6 +1849,9 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) drm_encoder_helper_add(encoder, &nv50_pior_help); drm_connector_attach_encoder(connector, encoder); + + disp->core->func->pior->get_caps(disp, nv_encoder, ffs(dcbe->or) - 1); + return 0; } @@ -2401,6 +2409,8 @@ nv50_display_destroy(struct drm_device *dev) nv50_audio_component_fini(nouveau_drm(dev)); + nvif_object_unmap(&disp->caps); + nvif_object_fini(&disp->caps); nv50_core_del(&disp->core); nouveau_bo_unmap(disp->sync); @@ -2462,6 +2472,11 @@ nv50_display_create(struct drm_device *dev) goto out; disp->core->func->init(disp->core); + if (disp->core->func->caps_init) { + ret = disp->core->func->caps_init(drm, disp); + if (ret) + goto out; + } /* Assign the correct format modifiers */ if (disp->disp->object.oclass >= TU102_DISP) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index 1743c3a76216..696e70a6b98b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -9,6 +9,7 @@ struct nv50_msto; struct nv50_disp { struct nvif_disp *disp; struct nv50_core *core; + struct nvif_object caps; #define NV50_DISP_SYNC(c, o) ((c) * 0x040 + (o)) #define NV50_DISP_CORE_NTFY NV50_DISP_SYNC(0 , 0x00) diff --git a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c index d2bac6a341dc..45d8ce7d2c28 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c @@ -38,7 +38,15 @@ pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl, } } +static void +pior507d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, + int or) +{ + outp->caps.dp_interlace = true; +} + const struct nv50_outp_func pior507d = { .ctrl = pior507d_ctrl, + .get_caps = pior507d_get_caps, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c index 5222fe6a9b21..9a59fa7da00d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c @@ -38,7 +38,14 @@ sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl, } } +static void +sor507d_get_caps(struct nv50_disp *core, struct nouveau_encoder *outp, int or) +{ + outp->caps.dp_interlace = true; +} + const struct nv50_outp_func sor507d = { .ctrl = sor507d_ctrl, + .get_caps = sor507d_get_caps, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor907d.c b/drivers/gpu/drm/nouveau/dispnv50/sor907d.c index b0314ec11fb3..9577ccf1c809 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sor907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sor907d.c @@ -21,6 +21,7 @@ */ #include "core.h" +#include #include static void @@ -35,7 +36,17 @@ sor907d_ctrl(struct nv50_core *core, int or, u32 ctrl, } } +static void +sor907d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, int or) +{ + const int off = or * 2; + u32 tmp = nouveau_bo_rd32(disp->sync, 0x000014 + off); + + outp->caps.dp_interlace = !!(tmp & 0x04000000); +} + const struct nv50_outp_func sor907d = { .ctrl = sor907d_ctrl, + .get_caps = sor907d_get_caps, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c b/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c index dff059241c5d..c86ca955fdcd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c @@ -33,7 +33,16 @@ sorc37d_ctrl(struct nv50_core *core, int or, u32 ctrl, } } +static void +sorc37d_get_caps(struct nv50_disp *disp, struct nouveau_encoder *outp, int or) +{ + u32 tmp = nvif_rd32(&disp->caps, 0x000144 + (or * 8)); + + outp->caps.dp_interlace = !!(tmp & 0x04000000); +} + const struct nv50_outp_func sorc37d = { .ctrl = sorc37d_ctrl, + .get_caps = sorc37d_get_caps, }; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 9a9a7f5003d3..6dae00da5d7e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -509,7 +509,11 @@ nouveau_connector_set_encoder(struct drm_connector *connector, nv_connector->detected_encoder = nv_encoder; if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - connector->interlace_allowed = true; + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) + connector->interlace_allowed = + nv_encoder->caps.dp_interlace; + else + connector->interlace_allowed = true; connector->doublescan_allowed = true; } else if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS || @@ -1060,6 +1064,10 @@ nouveau_connector_mode_valid(struct drm_connector *connector, case DCB_OUTPUT_TV: return get_slave_funcs(encoder)->mode_valid(encoder, mode); case DCB_OUTPUT_DP: + if (mode->flags & DRM_MODE_FLAG_INTERLACE && + !nv_encoder->caps.dp_interlace) + return MODE_NO_INTERLACE; + max_clock = nv_encoder->dp.link_nr; max_clock *= nv_encoder->dp.link_bw; clock = clock * (connector->display_info.bpc * 3) / 10; diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index 3517f920bf89..3217f587eceb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -66,6 +66,10 @@ struct nouveau_encoder { } dp; }; + struct { + bool dp_interlace : 1; + } caps; + void (*enc_save)(struct drm_encoder *encoder); void (*enc_restore)(struct drm_encoder *encoder); void (*update)(struct nouveau_encoder *, u8 head, -- cgit v1.2.3 From af620cf083cd29dfafb8021d423d567ab57654b1 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 11 May 2020 18:41:25 -0400 Subject: drm/nouveau/kms/gv100-: Add support for interlaced modes We advertise being able to set interlaced modes, so let's actually make sure to do that. Otherwise, we'll end up hanging the display engine due to trying to set a mode with timings adjusted for interlacing without telling the hardware it's actually an interlaced mode. Signed-off-by: Lyude Paul Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/headc37d.c | 5 +++-- drivers/gpu/drm/nouveau/dispnv50/headc57d.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c index 00011ce109a6..4a9a32b89f74 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c @@ -168,14 +168,15 @@ headc37d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; struct nv50_head_mode *m = &asyh->mode; u32 *push; - if ((push = evo_wait(core, 12))) { + if ((push = evo_wait(core, 13))) { evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5); evo_data(push, (m->v.active << 16) | m->h.active ); evo_data(push, (m->v.synce << 16) | m->h.synce ); evo_data(push, (m->v.blanke << 16) | m->h.blanke ); evo_data(push, (m->v.blanks << 16) | m->h.blanks ); evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x200c + (head->base.index * 0x400), 1); + evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2); + evo_data(push, m->interlace); evo_data(push, m->clock * 1000); evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); evo_data(push, m->clock * 1000); diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc57d.c b/drivers/gpu/drm/nouveau/dispnv50/headc57d.c index 938d910a1b1e..859131a8bc3c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headc57d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headc57d.c @@ -173,14 +173,15 @@ headc57d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; struct nv50_head_mode *m = &asyh->mode; u32 *push; - if ((push = evo_wait(core, 12))) { + if ((push = evo_wait(core, 13))) { evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5); evo_data(push, (m->v.active << 16) | m->h.active ); evo_data(push, (m->v.synce << 16) | m->h.synce ); evo_data(push, (m->v.blanke << 16) | m->h.blanke ); evo_data(push, (m->v.blanks << 16) | m->h.blanks ); evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x200c + (head->base.index * 0x400), 1); + evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2); + evo_data(push, m->interlace); evo_data(push, m->clock * 1000); evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); evo_data(push, m->clock * 1000); -- cgit v1.2.3 From bbdf6a5891fc46b23a91c16941cc8b18ff37ac43 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 11 May 2020 18:41:26 -0400 Subject: drm/nouveau/kms/nv50-: Move 8BPC limit for MST into nv50_mstc_get_modes() This just limits the BPC for MST connectors to a maximum of 8 from nv50_mstc_get_modes(), instead of doing so during nv50_msto_atomic_check(). This doesn't introduce any functional changes yet (other then userspace now lying about the max bpc, but we can't support that yet anyway so meh). But, we'll need this in a moment so that we can share mode validation between SST and MST which will fix some real world issues. Signed-off-by: Lyude Paul Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index e6a93fdfc6a2..ae2c90868caf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -908,15 +908,9 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, if (!state->duplicated) { const int clock = crtc_state->adjusted_mode.clock; - /* - * XXX: Since we don't use HDR in userspace quite yet, limit - * the bpc to 8 to save bandwidth on the topology. In the - * future, we'll want to properly fix this by dynamically - * selecting the highest possible bpc that would fit in the - * topology - */ - asyh->or.bpc = min(connector->display_info.bpc, 8U); - asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3, false); + asyh->or.bpc = connector->display_info.bpc; + asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3, + false); } slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, mstc->port, @@ -1076,8 +1070,17 @@ nv50_mstc_get_modes(struct drm_connector *connector) if (mstc->edid) ret = drm_add_edid_modes(&mstc->connector, mstc->edid); - if (!mstc->connector.display_info.bpc) - mstc->connector.display_info.bpc = 8; + /* + * XXX: Since we don't use HDR in userspace quite yet, limit the bpc + * to 8 to save bandwidth on the topology. In the future, we'll want + * to properly fix this by dynamically selecting the highest possible + * bpc that would fit in the topology + */ + if (connector->display_info.bpc) + connector->display_info.bpc = + clamp(connector->display_info.bpc, 6U, 8U); + else + connector->display_info.bpc = 8; if (mstc->native) drm_mode_destroy(mstc->connector.dev, mstc->native); -- cgit v1.2.3 From d6a9efece7248d3cbd7bf65d3a8325e8e5dceec0 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 11 May 2020 18:41:27 -0400 Subject: drm/nouveau/kms/nv50-: Share DP SST mode_valid() handling with MST Currently, the nv50_mstc_mode_valid() function is happy to take any and all modes, even the ones we can't actually support sometimes like interlaced modes. Luckily, the only difference between the mode validation that needs to be performed for MST vs. SST is that eventually we'll need to check the minimum PBN against the MSTB's full PBN capabilities (remember-we don't care about the current bw state here). Otherwise, all of the other code can be shared. So, we move all of the common mode validation in nouveau_connector_mode_valid() into a separate helper, nv50_dp_mode_valid(), and use that from both nv50_mstc_mode_valid() and nouveau_connector_mode_valid(). Note that we allow for returning the calculated clock that nv50_dp_mode_valid() came up with, since we'll eventually want to use that for PBN calculation in nv50_mstc_mode_valid(). Signed-off-by: Lyude Paul Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 9 +++++- drivers/gpu/drm/nouveau/nouveau_connector.c | 46 +++++++++++++++++------------ drivers/gpu/drm/nouveau/nouveau_connector.h | 5 ++++ drivers/gpu/drm/nouveau/nouveau_dp.c | 31 +++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_encoder.h | 4 +++ 5 files changed, 75 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index ae2c90868caf..8d60252e5583 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1056,7 +1056,14 @@ static enum drm_mode_status nv50_mstc_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - return MODE_OK; + struct nv50_mstc *mstc = nv50_mstc(connector); + struct nouveau_encoder *outp = mstc->mstm->outp; + + /* TODO: calculate the PBN from the dotclock and validate against the + * MSTB's max possible PBN + */ + + return nv50_dp_mode_valid(connector, outp, mode, NULL); } static int diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 6dae00da5d7e..1b383ae0248f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -38,6 +38,7 @@ #include "nouveau_reg.h" #include "nouveau_drv.h" #include "dispnv04/hw.h" +#include "dispnv50/disp.h" #include "nouveau_acpi.h" #include "nouveau_display.h" @@ -1033,6 +1034,29 @@ get_tmds_link_bandwidth(struct drm_connector *connector) return 112000 * duallink_scale; } +enum drm_mode_status +nouveau_conn_mode_clock_valid(const struct drm_display_mode *mode, + const unsigned min_clock, + const unsigned max_clock, + unsigned int *clock_out) +{ + unsigned int clock = mode->clock; + + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == + DRM_MODE_FLAG_3D_FRAME_PACKING) + clock *= 2; + + if (clock < min_clock) + return MODE_CLOCK_LOW; + if (clock > max_clock) + return MODE_CLOCK_HIGH; + + if (clock_out) + *clock_out = clock; + + return MODE_OK; +} + static enum drm_mode_status nouveau_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -1041,7 +1065,6 @@ nouveau_connector_mode_valid(struct drm_connector *connector, struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; struct drm_encoder *encoder = to_drm_encoder(nv_encoder); unsigned min_clock = 25000, max_clock = min_clock; - unsigned clock = mode->clock; switch (nv_encoder->dcb->type) { case DCB_OUTPUT_LVDS: @@ -1064,29 +1087,14 @@ nouveau_connector_mode_valid(struct drm_connector *connector, case DCB_OUTPUT_TV: return get_slave_funcs(encoder)->mode_valid(encoder, mode); case DCB_OUTPUT_DP: - if (mode->flags & DRM_MODE_FLAG_INTERLACE && - !nv_encoder->caps.dp_interlace) - return MODE_NO_INTERLACE; - - max_clock = nv_encoder->dp.link_nr; - max_clock *= nv_encoder->dp.link_bw; - clock = clock * (connector->display_info.bpc * 3) / 10; - break; + return nv50_dp_mode_valid(connector, nv_encoder, mode, NULL); default: BUG(); return MODE_BAD; } - if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) - clock *= 2; - - if (clock < min_clock) - return MODE_CLOCK_LOW; - - if (clock > max_clock) - return MODE_CLOCK_HIGH; - - return MODE_OK; + return nouveau_conn_mode_clock_valid(mode, min_clock, max_clock, + NULL); } static struct drm_encoder * diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index de84fb4708c7..9e062c7adec8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -195,6 +195,11 @@ int nouveau_conn_atomic_get_property(struct drm_connector *, const struct drm_connector_state *, struct drm_property *, u64 *); struct drm_display_mode *nouveau_conn_native_mode(struct drm_connector *); +enum drm_mode_status +nouveau_conn_mode_clock_valid(const struct drm_display_mode *, + const unsigned min_clock, + const unsigned max_clock, + unsigned *clock); #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT extern int nouveau_backlight_init(struct drm_connector *); diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 2674f1587457..8a0f7994e1ae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -98,3 +98,34 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder) return NOUVEAU_DP_SST; return ret; } + +/* TODO: + * - Use the minimum possible BPC here, once we add support for the max bpc + * property. + * - Validate the mode against downstream port caps (see + * drm_dp_downstream_max_clock()) + * - Validate against the DP caps advertised by the GPU (we don't check these + * yet) + */ +enum drm_mode_status +nv50_dp_mode_valid(struct drm_connector *connector, + struct nouveau_encoder *outp, + const struct drm_display_mode *mode, + unsigned *out_clock) +{ + const unsigned min_clock = 25000; + unsigned max_clock, clock; + enum drm_mode_status ret; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE && !outp->caps.dp_interlace) + return MODE_NO_INTERLACE; + + max_clock = outp->dp.link_nr * outp->dp.link_bw; + clock = mode->clock * (connector->display_info.bpc * 3) / 10; + + ret = nouveau_conn_mode_clock_valid(mode, min_clock, max_clock, + &clock); + if (out_clock) + *out_clock = clock; + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index 3217f587eceb..de51733b0476 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -104,6 +104,10 @@ enum nouveau_dp_status { }; int nouveau_dp_detect(struct nouveau_encoder *); +enum drm_mode_status nv50_dp_mode_valid(struct drm_connector *, + struct nouveau_encoder *, + const struct drm_display_mode *, + unsigned *clock); struct nouveau_connector * nouveau_encoder_connector_get(struct nouveau_encoder *encoder); -- cgit v1.2.3 From 1d7f940c3a16623adb25706b10d81f8b822d53f9 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Tue, 21 Apr 2020 16:11:07 -0700 Subject: drm/nouveau/nouveau/hmm: fix nouveau_dmem_chunk allocations In nouveau_dmem_init(), a number of struct nouveau_dmem_chunk are allocated and put on the dmem->chunk_empty list. Then in nouveau_dmem_pages_alloc(), a nouveau_dmem_chunk is removed from the list and GPU memory is allocated. However, the nouveau_dmem_chunk is never removed from the chunk_empty list nor placed on the chunk_free or chunk_full lists. This results in only one chunk ever being actually used (2MB) and quickly leads to migration to device private memory failures. Fix this by having just one list of free device private pages and if no pages are free, allocate a chunk of device private pages and GPU memory. Signed-off-by: Ralph Campbell Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_dmem.c | 304 ++++++++++++--------------------- 1 file changed, 112 insertions(+), 192 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index a2ef8d562867..c39500a84b17 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -61,10 +61,8 @@ struct nouveau_dmem_chunk { struct list_head list; struct nouveau_bo *bo; struct nouveau_drm *drm; - unsigned long pfn_first; unsigned long callocated; - unsigned long bitmap[BITS_TO_LONGS(DMEM_CHUNK_NPAGES)]; - spinlock_t lock; + struct dev_pagemap pagemap; }; struct nouveau_dmem_migrate { @@ -74,48 +72,50 @@ struct nouveau_dmem_migrate { struct nouveau_dmem { struct nouveau_drm *drm; - struct dev_pagemap pagemap; struct nouveau_dmem_migrate migrate; - struct list_head chunk_free; - struct list_head chunk_full; - struct list_head chunk_empty; + struct list_head chunks; struct mutex mutex; + struct page *free_pages; + spinlock_t lock; }; -static inline struct nouveau_dmem *page_to_dmem(struct page *page) +static struct nouveau_dmem_chunk *nouveau_page_to_chunk(struct page *page) +{ + return container_of(page->pgmap, struct nouveau_dmem_chunk, pagemap); +} + +static struct nouveau_drm *page_to_drm(struct page *page) { - return container_of(page->pgmap, struct nouveau_dmem, pagemap); + struct nouveau_dmem_chunk *chunk = nouveau_page_to_chunk(page); + + return chunk->drm; } static unsigned long nouveau_dmem_page_addr(struct page *page) { - struct nouveau_dmem_chunk *chunk = page->zone_device_data; - unsigned long idx = page_to_pfn(page) - chunk->pfn_first; + struct nouveau_dmem_chunk *chunk = nouveau_page_to_chunk(page); + unsigned long off = (page_to_pfn(page) << PAGE_SHIFT) - + chunk->pagemap.res.start; - return (idx << PAGE_SHIFT) + chunk->bo->bo.offset; + return chunk->bo->bo.offset + off; } static void nouveau_dmem_page_free(struct page *page) { - struct nouveau_dmem_chunk *chunk = page->zone_device_data; - unsigned long idx = page_to_pfn(page) - chunk->pfn_first; + struct nouveau_dmem_chunk *chunk = nouveau_page_to_chunk(page); + struct nouveau_dmem *dmem = chunk->drm->dmem; + + spin_lock(&dmem->lock); + page->zone_device_data = dmem->free_pages; + dmem->free_pages = page; - /* - * FIXME: - * - * This is really a bad example, we need to overhaul nouveau memory - * management to be more page focus and allow lighter locking scheme - * to be use in the process. - */ - spin_lock(&chunk->lock); - clear_bit(idx, chunk->bitmap); WARN_ON(!chunk->callocated); chunk->callocated--; /* * FIXME when chunk->callocated reach 0 we should add the chunk to * a reclaim list so that it can be freed in case of memory pressure. */ - spin_unlock(&chunk->lock); + spin_unlock(&dmem->lock); } static void nouveau_dmem_fence_done(struct nouveau_fence **fence) @@ -167,8 +167,8 @@ error_free_page: static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf) { - struct nouveau_dmem *dmem = page_to_dmem(vmf->page); - struct nouveau_drm *drm = dmem->drm; + struct nouveau_drm *drm = page_to_drm(vmf->page); + struct nouveau_dmem *dmem = drm->dmem; struct nouveau_fence *fence; unsigned long src = 0, dst = 0; dma_addr_t dma_addr = 0; @@ -211,131 +211,105 @@ static const struct dev_pagemap_ops nouveau_dmem_pagemap_ops = { }; static int -nouveau_dmem_chunk_alloc(struct nouveau_drm *drm) +nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage) { struct nouveau_dmem_chunk *chunk; + struct resource *res; + struct page *page; + void *ptr; + unsigned long i, pfn_first; int ret; - if (drm->dmem == NULL) - return -EINVAL; - - mutex_lock(&drm->dmem->mutex); - chunk = list_first_entry_or_null(&drm->dmem->chunk_empty, - struct nouveau_dmem_chunk, - list); + chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); if (chunk == NULL) { - mutex_unlock(&drm->dmem->mutex); - return -ENOMEM; + ret = -ENOMEM; + goto out; } - list_del(&chunk->list); - mutex_unlock(&drm->dmem->mutex); + /* Allocate unused physical address space for device private pages. */ + res = request_free_mem_region(&iomem_resource, DMEM_CHUNK_SIZE, + "nouveau_dmem"); + if (IS_ERR(res)) { + ret = PTR_ERR(res); + goto out_free; + } + + chunk->drm = drm; + chunk->pagemap.type = MEMORY_DEVICE_PRIVATE; + chunk->pagemap.res = *res; + chunk->pagemap.ops = &nouveau_dmem_pagemap_ops; + chunk->pagemap.owner = drm->dev; ret = nouveau_bo_new(&drm->client, DMEM_CHUNK_SIZE, 0, TTM_PL_FLAG_VRAM, 0, 0, NULL, NULL, &chunk->bo); if (ret) - goto out; + goto out_release; ret = nouveau_bo_pin(chunk->bo, TTM_PL_FLAG_VRAM, false); - if (ret) { - nouveau_bo_ref(NULL, &chunk->bo); - goto out; - } + if (ret) + goto out_bo_free; - bitmap_zero(chunk->bitmap, DMEM_CHUNK_NPAGES); - spin_lock_init(&chunk->lock); + ptr = memremap_pages(&chunk->pagemap, numa_node_id()); + if (IS_ERR(ptr)) { + ret = PTR_ERR(ptr); + goto out_bo_unpin; + } -out: mutex_lock(&drm->dmem->mutex); - if (chunk->bo) - list_add(&chunk->list, &drm->dmem->chunk_empty); - else - list_add_tail(&chunk->list, &drm->dmem->chunk_empty); + list_add(&chunk->list, &drm->dmem->chunks); mutex_unlock(&drm->dmem->mutex); - return ret; -} - -static struct nouveau_dmem_chunk * -nouveau_dmem_chunk_first_free_locked(struct nouveau_drm *drm) -{ - struct nouveau_dmem_chunk *chunk; - - chunk = list_first_entry_or_null(&drm->dmem->chunk_free, - struct nouveau_dmem_chunk, - list); - if (chunk) - return chunk; - - chunk = list_first_entry_or_null(&drm->dmem->chunk_empty, - struct nouveau_dmem_chunk, - list); - if (chunk->bo) - return chunk; - - return NULL; -} - -static int -nouveau_dmem_pages_alloc(struct nouveau_drm *drm, - unsigned long npages, - unsigned long *pages) -{ - struct nouveau_dmem_chunk *chunk; - unsigned long c; - int ret; - - memset(pages, 0xff, npages * sizeof(*pages)); - - mutex_lock(&drm->dmem->mutex); - for (c = 0; c < npages;) { - unsigned long i; - - chunk = nouveau_dmem_chunk_first_free_locked(drm); - if (chunk == NULL) { - mutex_unlock(&drm->dmem->mutex); - ret = nouveau_dmem_chunk_alloc(drm); - if (ret) { - if (c) - return 0; - return ret; - } - mutex_lock(&drm->dmem->mutex); - continue; - } - - spin_lock(&chunk->lock); - i = find_first_zero_bit(chunk->bitmap, DMEM_CHUNK_NPAGES); - while (i < DMEM_CHUNK_NPAGES && c < npages) { - pages[c] = chunk->pfn_first + i; - set_bit(i, chunk->bitmap); - chunk->callocated++; - c++; - - i = find_next_zero_bit(chunk->bitmap, - DMEM_CHUNK_NPAGES, i); - } - spin_unlock(&chunk->lock); + pfn_first = chunk->pagemap.res.start >> PAGE_SHIFT; + page = pfn_to_page(pfn_first); + spin_lock(&drm->dmem->lock); + for (i = 0; i < DMEM_CHUNK_NPAGES - 1; ++i, ++page) { + page->zone_device_data = drm->dmem->free_pages; + drm->dmem->free_pages = page; } - mutex_unlock(&drm->dmem->mutex); + *ppage = page; + chunk->callocated++; + spin_unlock(&drm->dmem->lock); + + NV_INFO(drm, "DMEM: registered %ldMB of device memory\n", + DMEM_CHUNK_SIZE >> 20); return 0; + +out_bo_unpin: + nouveau_bo_unpin(chunk->bo); +out_bo_free: + nouveau_bo_ref(NULL, &chunk->bo); +out_release: + release_mem_region(chunk->pagemap.res.start, + resource_size(&chunk->pagemap.res)); +out_free: + kfree(chunk); +out: + return ret; } static struct page * nouveau_dmem_page_alloc_locked(struct nouveau_drm *drm) { - unsigned long pfns[1]; - struct page *page; + struct nouveau_dmem_chunk *chunk; + struct page *page = NULL; int ret; - /* FIXME stop all the miss-match API ... */ - ret = nouveau_dmem_pages_alloc(drm, 1, pfns); - if (ret) - return NULL; + spin_lock(&drm->dmem->lock); + if (drm->dmem->free_pages) { + page = drm->dmem->free_pages; + drm->dmem->free_pages = page->zone_device_data; + chunk = nouveau_page_to_chunk(page); + chunk->callocated++; + spin_unlock(&drm->dmem->lock); + } else { + spin_unlock(&drm->dmem->lock); + ret = nouveau_dmem_chunk_alloc(drm, &page); + if (ret) + return NULL; + } - page = pfn_to_page(pfns[0]); get_page(page); lock_page(page); return page; @@ -358,12 +332,7 @@ nouveau_dmem_resume(struct nouveau_drm *drm) return; mutex_lock(&drm->dmem->mutex); - list_for_each_entry (chunk, &drm->dmem->chunk_free, list) { - ret = nouveau_bo_pin(chunk->bo, TTM_PL_FLAG_VRAM, false); - /* FIXME handle pin failure */ - WARN_ON(ret); - } - list_for_each_entry (chunk, &drm->dmem->chunk_full, list) { + list_for_each_entry(chunk, &drm->dmem->chunks, list) { ret = nouveau_bo_pin(chunk->bo, TTM_PL_FLAG_VRAM, false); /* FIXME handle pin failure */ WARN_ON(ret); @@ -380,12 +349,8 @@ nouveau_dmem_suspend(struct nouveau_drm *drm) return; mutex_lock(&drm->dmem->mutex); - list_for_each_entry (chunk, &drm->dmem->chunk_free, list) { - nouveau_bo_unpin(chunk->bo); - } - list_for_each_entry (chunk, &drm->dmem->chunk_full, list) { + list_for_each_entry(chunk, &drm->dmem->chunks, list) nouveau_bo_unpin(chunk->bo); - } mutex_unlock(&drm->dmem->mutex); } @@ -399,15 +364,13 @@ nouveau_dmem_fini(struct nouveau_drm *drm) mutex_lock(&drm->dmem->mutex); - WARN_ON(!list_empty(&drm->dmem->chunk_free)); - WARN_ON(!list_empty(&drm->dmem->chunk_full)); - - list_for_each_entry_safe (chunk, tmp, &drm->dmem->chunk_empty, list) { - if (chunk->bo) { - nouveau_bo_unpin(chunk->bo); - nouveau_bo_ref(NULL, &chunk->bo); - } + list_for_each_entry_safe(chunk, tmp, &drm->dmem->chunks, list) { + nouveau_bo_unpin(chunk->bo); + nouveau_bo_ref(NULL, &chunk->bo); list_del(&chunk->list); + memunmap_pages(&chunk->pagemap); + release_mem_region(chunk->pagemap.res.start, + resource_size(&chunk->pagemap.res)); kfree(chunk); } @@ -493,9 +456,6 @@ nouveau_dmem_migrate_init(struct nouveau_drm *drm) void nouveau_dmem_init(struct nouveau_drm *drm) { - struct device *device = drm->dev->dev; - struct resource *res; - unsigned long i, size, pfn_first; int ret; /* This only make sense on PASCAL or newer */ @@ -507,59 +467,16 @@ nouveau_dmem_init(struct nouveau_drm *drm) drm->dmem->drm = drm; mutex_init(&drm->dmem->mutex); - INIT_LIST_HEAD(&drm->dmem->chunk_free); - INIT_LIST_HEAD(&drm->dmem->chunk_full); - INIT_LIST_HEAD(&drm->dmem->chunk_empty); - - size = ALIGN(drm->client.device.info.ram_user, DMEM_CHUNK_SIZE); + INIT_LIST_HEAD(&drm->dmem->chunks); + mutex_init(&drm->dmem->mutex); + spin_lock_init(&drm->dmem->lock); /* Initialize migration dma helpers before registering memory */ ret = nouveau_dmem_migrate_init(drm); - if (ret) - goto out_free; - - /* - * FIXME we need some kind of policy to decide how much VRAM we - * want to register with HMM. For now just register everything - * and latter if we want to do thing like over commit then we - * could revisit this. - */ - res = devm_request_free_mem_region(device, &iomem_resource, size); - if (IS_ERR(res)) - goto out_free; - drm->dmem->pagemap.type = MEMORY_DEVICE_PRIVATE; - drm->dmem->pagemap.res = *res; - drm->dmem->pagemap.ops = &nouveau_dmem_pagemap_ops; - drm->dmem->pagemap.owner = drm->dev; - if (IS_ERR(devm_memremap_pages(device, &drm->dmem->pagemap))) - goto out_free; - - pfn_first = res->start >> PAGE_SHIFT; - for (i = 0; i < (size / DMEM_CHUNK_SIZE); ++i) { - struct nouveau_dmem_chunk *chunk; - struct page *page; - unsigned long j; - - chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); - if (chunk == NULL) { - nouveau_dmem_fini(drm); - return; - } - - chunk->drm = drm; - chunk->pfn_first = pfn_first + (i * DMEM_CHUNK_NPAGES); - list_add_tail(&chunk->list, &drm->dmem->chunk_empty); - - page = pfn_to_page(chunk->pfn_first); - for (j = 0; j < DMEM_CHUNK_NPAGES; ++j, ++page) - page->zone_device_data = chunk; + if (ret) { + kfree(drm->dmem); + drm->dmem = NULL; } - - NV_INFO(drm, "DMEM: registered %ldMB of device memory\n", size >> 20); - return; -out_free: - kfree(drm->dmem); - drm->dmem = NULL; } static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm, @@ -646,6 +563,9 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm, u64 *pfns; int ret = -ENOMEM; + if (drm->dmem == NULL) + return -ENODEV; + args.src = kcalloc(max, sizeof(*args.src), GFP_KERNEL); if (!args.src) goto out; -- cgit v1.2.3 From 9d4296a7d4b329016e6b5b59a7fb3f8afa36ac05 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Wed, 20 May 2020 11:36:52 -0700 Subject: drm/nouveau/nouveau/hmm: fix migrate zero page to GPU When calling OpenCL clEnqueueSVMMigrateMem() on a region of memory that is backed by pte_none() or zero pages, migrate_vma_setup() will fill the source PFN array with an entry indicating the source page is zero. Use this to optimize migration to device private memory by allocating GPU memory and zero filling it instead of failing to migrate the page. Signed-off-by: Ralph Campbell Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_dmem.c | 75 ++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index c39500a84b17..339a0c387eae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -56,6 +56,8 @@ enum nouveau_aper { typedef int (*nouveau_migrate_copy_t)(struct nouveau_drm *drm, u64 npages, enum nouveau_aper, u64 dst_addr, enum nouveau_aper, u64 src_addr); +typedef int (*nouveau_clear_page_t)(struct nouveau_drm *drm, u32 length, + enum nouveau_aper, u64 dst_addr); struct nouveau_dmem_chunk { struct list_head list; @@ -67,6 +69,7 @@ struct nouveau_dmem_chunk { struct nouveau_dmem_migrate { nouveau_migrate_copy_t copy_func; + nouveau_clear_page_t clear_func; struct nouveau_channel *chan; }; @@ -436,6 +439,52 @@ nvc0b5_migrate_copy(struct nouveau_drm *drm, u64 npages, return 0; } +static int +nvc0b5_migrate_clear(struct nouveau_drm *drm, u32 length, + enum nouveau_aper dst_aper, u64 dst_addr) +{ + struct nouveau_channel *chan = drm->dmem->migrate.chan; + u32 launch_dma = (1 << 10) /* REMAP_ENABLE_TRUE */ | + (1 << 8) /* DST_MEMORY_LAYOUT_PITCH. */ | + (1 << 7) /* SRC_MEMORY_LAYOUT_PITCH. */ | + (1 << 2) /* FLUSH_ENABLE_TRUE. */ | + (2 << 0) /* DATA_TRANSFER_TYPE_NON_PIPELINED. */; + u32 remap = (4 << 0) /* DST_X_CONST_A */ | + (5 << 4) /* DST_Y_CONST_B */ | + (3 << 16) /* COMPONENT_SIZE_FOUR */ | + (1 << 24) /* NUM_DST_COMPONENTS_TWO */; + int ret; + + ret = RING_SPACE(chan, 12); + if (ret) + return ret; + + switch (dst_aper) { + case NOUVEAU_APER_VRAM: + BEGIN_IMC0(chan, NvSubCopy, 0x0264, 0); + break; + case NOUVEAU_APER_HOST: + BEGIN_IMC0(chan, NvSubCopy, 0x0264, 1); + break; + default: + return -EINVAL; + } + launch_dma |= 0x00002000; /* DST_TYPE_PHYSICAL. */ + + BEGIN_NVC0(chan, NvSubCopy, 0x0700, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, remap); + BEGIN_NVC0(chan, NvSubCopy, 0x0408, 2); + OUT_RING(chan, upper_32_bits(dst_addr)); + OUT_RING(chan, lower_32_bits(dst_addr)); + BEGIN_NVC0(chan, NvSubCopy, 0x0418, 1); + OUT_RING(chan, length >> 3); + BEGIN_NVC0(chan, NvSubCopy, 0x0300, 1); + OUT_RING(chan, launch_dma); + return 0; +} + static int nouveau_dmem_migrate_init(struct nouveau_drm *drm) { @@ -445,6 +494,7 @@ nouveau_dmem_migrate_init(struct nouveau_drm *drm) case VOLTA_DMA_COPY_A: case TURING_DMA_COPY_A: drm->dmem->migrate.copy_func = nvc0b5_migrate_copy; + drm->dmem->migrate.clear_func = nvc0b5_migrate_clear; drm->dmem->migrate.chan = drm->ttm.chan; return 0; default: @@ -487,21 +537,28 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm, unsigned long paddr; spage = migrate_pfn_to_page(src); - if (!spage || !(src & MIGRATE_PFN_MIGRATE)) + if (!(src & MIGRATE_PFN_MIGRATE)) goto out; dpage = nouveau_dmem_page_alloc_locked(drm); if (!dpage) goto out; - *dma_addr = dma_map_page(dev, spage, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, *dma_addr)) - goto out_free_page; - paddr = nouveau_dmem_page_addr(dpage); - if (drm->dmem->migrate.copy_func(drm, 1, NOUVEAU_APER_VRAM, - paddr, NOUVEAU_APER_HOST, *dma_addr)) - goto out_dma_unmap; + if (spage) { + *dma_addr = dma_map_page(dev, spage, 0, page_size(spage), + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, *dma_addr)) + goto out_free_page; + if (drm->dmem->migrate.copy_func(drm, page_size(spage), + NOUVEAU_APER_VRAM, paddr, NOUVEAU_APER_HOST, *dma_addr)) + goto out_dma_unmap; + } else { + *dma_addr = DMA_MAPPING_ERROR; + if (drm->dmem->migrate.clear_func(drm, page_size(dpage), + NOUVEAU_APER_VRAM, paddr)) + goto out_free_page; + } *pfn = NVIF_VMM_PFNMAP_V0_V | NVIF_VMM_PFNMAP_V0_VRAM | ((paddr >> PAGE_SHIFT) << NVIF_VMM_PFNMAP_V0_ADDR_SHIFT); @@ -528,7 +585,7 @@ static void nouveau_dmem_migrate_chunk(struct nouveau_drm *drm, for (i = 0; addr < args->end; i++) { args->dst[i] = nouveau_dmem_migrate_copy_one(drm, args->src[i], dma_addrs + nr_dma, pfns + i); - if (args->dst[i]) + if (!dma_mapping_error(drm->dev->dev, dma_addrs[nr_dma])) nr_dma++; addr += PAGE_SIZE; } -- cgit v1.2.3 From 00583fbe8031f69bba8b0a9a861efb75fb7131af Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Wed, 20 May 2020 18:14:53 +0800 Subject: drm/nouveau/debugfs: fix runtime pm imbalance on error pm_runtime_get_sync() increments the runtime PM usage counter even the call returns an error code. Thus a pairing decrement is needed on the error handling path to keep the counter balanced. Signed-off-by: Dinghao Liu Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_debugfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 63cb5e432f8a..63b5c8cf9ae4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -181,8 +181,11 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf, } ret = pm_runtime_get_sync(drm->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(drm->dev); return ret; + } + ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args)); pm_runtime_put_autosuspend(drm->dev); if (ret < 0) -- cgit v1.2.3 From d7372dfb3f7f1602b87e0663e8b8646da23ebca7 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Wed, 20 May 2020 18:25:49 +0800 Subject: drm/nouveau: fix runtime pm imbalance on error pm_runtime_get_sync() increments the runtime PM usage counter even the call returns an error code. Thus a pairing decrement is needed on the error handling path to keep the counter balanced. Signed-off-by: Dinghao Liu Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index f5ece1f94973..6697f960dd89 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -76,8 +76,10 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) return ret; ret = pm_runtime_get_sync(dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev); goto out; + } ret = nouveau_vma_new(nvbo, vmm, &vma); pm_runtime_mark_last_busy(dev); -- cgit v1.2.3 From d3faddc7dcd326c0edc906f907f83a8454986d99 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Wed, 20 May 2020 18:36:04 +0800 Subject: drm/nouveau: fix runtime pm imbalance on error pm_runtime_get_sync() increments the runtime PM usage counter even the call returns an error code. Thus a pairing decrement is needed on the error handling path to keep the counter balanced. Signed-off-by: Dinghao Liu Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 6697f960dd89..4c3f131ad31d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -159,8 +159,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) if (!WARN_ON(ret < 0 && ret != -EACCES)) { nouveau_gem_object_unmap(nvbo, vma); pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); } + pm_runtime_put_autosuspend(dev); } } ttm_bo_unreserve(&nvbo->bo); -- cgit v1.2.3 From dc455f4c888365595c0a13da445e092422d55b8d Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Wed, 20 May 2020 18:47:48 +0800 Subject: drm/nouveau/dispnv50: fix runtime pm imbalance on error pm_runtime_get_sync() increments the runtime PM usage counter even the call returns an error code. Thus a pairing decrement is needed on the error handling path to keep the counter balanced. Signed-off-by: Dinghao Liu Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 8d60252e5583..7622490d8602 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1137,8 +1137,10 @@ nv50_mstc_detect(struct drm_connector *connector, return connector_status_disconnected; ret = pm_runtime_get_sync(connector->dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } ret = drm_dp_mst_detect_port(connector, ctx, mstc->port->mgr, mstc->port); -- cgit v1.2.3 From 7dbbdd37f2ae7dd4175ba3f86f4335c463b18403 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 26 May 2020 14:18:27 +1000 Subject: drm/nouveau: use correct conflicting framebuffer API nouveau was calling the fbdev API which has issues with modules and built-ins. Call the correct API. Reported-by: Randy Dunlap Acked-by: Randy Dunlap # build-tested Fixes: 2dd4d163cd9c ("drm/nouveau: remove open-coded version of remove_conflicting_pci_framebuffers()") Link: https://lore.kernel.org/lkml/21b52c28-3ace-cd13-d8ce-f38f2c6b2a96@infradead.org/T/#u Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/nouveau') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index eb10c80ed853..ac93d12201dc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -697,7 +697,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev, nvkm_device_del(&device); /* Remove conflicting drivers (vesafb, efifb etc). */ - ret = remove_conflicting_pci_framebuffers(pdev, "nouveaufb"); + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "nouveaufb"); if (ret) return ret; -- cgit v1.2.3