From 7caa63c04029c5882865867470c106ef73eafb2b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Aug 2014 11:36:45 +1000 Subject: [PATCH 01/12] drm/nouveau/nvif: fix a number of notify thinkos Note to self: more sleep Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/core/client.c | 4 +-- .../drm/nouveau/core/include/core/client.h | 2 +- drivers/gpu/drm/nouveau/nvif/notify.c | 25 +++++++++++++------ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index 10598dede9e9..68bf06768123 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c @@ -132,12 +132,12 @@ nvkm_client_notify_new(struct nouveau_client *client, if (ret == 0) { client->notify[index] = notify; notify->client = client; - return 0; + return index; } } kfree(notify); - return 0; + return ret; } static int diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h index 4fc6ab12382d..1794a05205d8 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/drivers/gpu/drm/nouveau/core/include/core/client.h @@ -14,7 +14,7 @@ struct nouveau_client { void *data; int (*ntfy)(const void *, u32, const void *, u32); - struct nvkm_client_notify *notify[8]; + struct nvkm_client_notify *notify[16]; }; static inline struct nouveau_client * diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 7c06123a559c..7e03cdd17827 100644 --- a/drivers/gpu/drm/nouveau/nvif/notify.c +++ b/drivers/gpu/drm/nouveau/nvif/notify.c @@ -87,12 +87,25 @@ nvif_notify_get(struct nvif_notify *notify) return 0; } +static inline int +nvif_notify_func(struct nvif_notify *notify, bool keep) +{ + int ret = notify->func(notify); + if (ret == NVIF_NOTIFY_KEEP || + !test_and_clear_bit(NVKM_NOTIFY_USER, ¬ify->flags)) { + if (!keep) + atomic_dec(¬ify->putcnt); + else + nvif_notify_get_(notify); + } + return ret; +} + static void nvif_notify_work(struct work_struct *work) { struct nvif_notify *notify = container_of(work, typeof(*notify), work); - if (notify->func(notify) == NVIF_NOTIFY_KEEP) - nvif_notify_get_(notify); + nvif_notify_func(notify, true); } int @@ -113,19 +126,15 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size) if (!WARN_ON(notify == NULL)) { struct nvif_client *client = nvif_client(notify->object); if (!WARN_ON(notify->size != size)) { + atomic_inc(¬ify->putcnt); if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { - atomic_inc(¬ify->putcnt); memcpy((void *)notify->data, data, size); schedule_work(¬ify->work); return NVIF_NOTIFY_DROP; } notify->data = data; - ret = notify->func(notify); + ret = nvif_notify_func(notify, client->driver->keep); notify->data = NULL; - if (ret != NVIF_NOTIFY_DROP && client->driver->keep) { - atomic_inc(¬ify->putcnt); - nvif_notify_get_(notify); - } } } From 5c13cac149b96910291b00bc7953ce984efc4fbc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 10 Aug 2014 12:39:09 +1000 Subject: [PATCH 02/12] drm/nouveau: kill unused variable warning if !__OS_HAS_AGP Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index da5d631aa5b9..01da508625f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1228,7 +1228,6 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; struct nouveau_drm *drm = nouveau_bdev(bdev); struct nouveau_mem *node = mem->mm_node; - struct drm_device *dev = drm->dev; int ret; mem->bus.addr = NULL; @@ -1247,7 +1246,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) if (drm->agp.stat == ENABLED) { mem->bus.offset = mem->start << PAGE_SHIFT; mem->bus.base = drm->agp.base; - mem->bus.is_iomem = !dev->agp->cant_use_aperture; + mem->bus.is_iomem = !drm->dev->agp->cant_use_aperture; } #endif if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA || !node->memtype) From e715396ae3d55c4369ac3438e589a440780bc5ba Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Sun, 10 Aug 2014 12:36:26 +1000 Subject: [PATCH 03/12] drm/nouveau/kms: nouveau_fbcon_accel_fini can be static Signed-off-by: Fengguang Wu Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ebfe3180109e..8bdd27091db8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -226,7 +226,7 @@ nouveau_fbcon_accel_restore(struct drm_device *dev) } } -void +static void nouveau_fbcon_accel_fini(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); @@ -246,7 +246,7 @@ nouveau_fbcon_accel_fini(struct drm_device *dev) } } -void +static void nouveau_fbcon_accel_init(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); From e7d96929a7cd93e146af0d1fd251fa1ec2e3ebf8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Aug 2014 11:52:44 +1000 Subject: [PATCH 04/12] drm/nouveau/bar: behave better if ioremap failed Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/bar/base.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c index 73b1ed20c8d5..8bcbdf39cfb2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c @@ -99,8 +99,13 @@ nouveau_bar_alloc(struct nouveau_bar *bar, struct nouveau_object *parent, struct nouveau_mem *mem, struct nouveau_object **pobject) { struct nouveau_object *engine = nv_object(bar); - return nouveau_object_ctor(parent, engine, &nouveau_barobj_oclass, - mem, 0, pobject); + int ret = -ENOMEM; + if (bar->iomem) { + ret = nouveau_object_ctor(parent, engine, + &nouveau_barobj_oclass, + mem, 0, pobject); + } + return ret; } int @@ -118,9 +123,12 @@ nouveau_bar_create_(struct nouveau_object *parent, if (ret) return ret; - if (nv_device_resource_len(device, 3) != 0) + if (nv_device_resource_len(device, 3) != 0) { bar->iomem = ioremap(nv_device_resource_start(device, 3), nv_device_resource_len(device, 3)); + if (!bar->iomem) + nv_warn(bar, "PRAMIN ioremap failed\n"); + } return 0; } From 3d9e3921f4d77bcaeea913c48b894d1208f0cb06 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Aug 2014 09:17:41 +1000 Subject: [PATCH 05/12] drm/nvc0-/fb/ram: fix use of non-existant ram if partitions aren't uniform Likely a large part of the GK106 woes.. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c index 946518572346..2b284b192763 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c @@ -554,13 +554,13 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, } else { /* otherwise, address lowest common amount from 0GiB */ ret = nouveau_mm_init(&pfb->vram, rsvd_head, - (bsize << 8) * parts, 1); + (bsize << 8) * parts - rsvd_head, 1); if (ret) return ret; /* and the rest starting from (8GiB + common_size) */ offset = (0x0200000000ULL >> 12) + (bsize << 8); - length = (ram->size >> 12) - (bsize << 8) - rsvd_tail; + length = (ram->size >> 12) - ((bsize * parts) << 8) - rsvd_tail; ret = nouveau_mm_init(&pfb->vram, offset, length, 0); if (ret) From 147ed897e807e1a6e2c6fd9dc91830f1d2831d43 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Aug 2014 09:27:54 +1000 Subject: [PATCH 06/12] drm/nouveau/ltc: fix tag base address getting truncated if above 4GiB Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c index 9e00a1ede120..b54b582e72c4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c @@ -156,7 +156,7 @@ gf100_ltc_init_tag_ram(struct nouveau_fb *pfb, struct nvkm_ltc_priv *priv) if (ret) { priv->num_tags = 0; } else { - u64 tag_base = (priv->tag_ram->offset << 12) + tag_margin; + u64 tag_base = ((u64)priv->tag_ram->offset << 12) + tag_margin; tag_base += tag_align - 1; ret = do_div(tag_base, tag_align); From ef07ceae02271ac6eadc9f5cd652bb7162455a1b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Aug 2014 22:56:09 +1000 Subject: [PATCH 07/12] drm/nouveau/nvif: return null pointers on failure, in addition to ret != 0 Reported by Coverity. The intention is that the return value is checked, but let's be more paranoid and make it extremely obvious if something forgets to. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvif/notify.c | 4 +++- drivers/gpu/drm/nouveau/nvif/object.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 7e03cdd17827..0898c3155292 100644 --- a/drivers/gpu/drm/nouveau/nvif/notify.c +++ b/drivers/gpu/drm/nouveau/nvif/notify.c @@ -237,8 +237,10 @@ nvif_notify_new(struct nvif_object *object, int (*func)(struct nvif_notify *), if (notify) { int ret = nvif_notify_init(object, nvif_notify_del, func, work, type, data, size, reply, notify); - if (ret) + if (ret) { kfree(notify); + notify = NULL; + } *pnotify = notify; return ret; } diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index b0c82206ece2..dd85b56f6aa5 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -275,8 +275,10 @@ nvif_object_new(struct nvif_object *parent, u32 handle, u32 oclass, if (object) { int ret = nvif_object_init(parent, nvif_object_del, handle, oclass, data, size, object); - if (ret) + if (ret) { kfree(object); + object = NULL; + } *pobject = object; return ret; } From da7c74ea2b0e218ddd6c3d01ea55a12104e7c6fd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Aug 2014 23:11:18 +1000 Subject: [PATCH 08/12] drm/gf100-/gr: fix -ENOSPC detection when allocating zbc table entries Spotted by Coverity. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index db19191176fa..30fd1dc64f93 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -68,6 +68,9 @@ nvc0_graph_zbc_color_get(struct nvc0_graph_priv *priv, int format, } } + if (zbc < 0) + return zbc; + memcpy(priv->zbc_color[zbc].ds, ds, sizeof(priv->zbc_color[zbc].ds)); memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2)); priv->zbc_color[zbc].format = format; @@ -109,6 +112,9 @@ nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format, } } + if (zbc < 0) + return zbc; + priv->zbc_depth[zbc].format = format; priv->zbc_depth[zbc].ds = ds; priv->zbc_depth[zbc].l2 = l2; From 8bd62a8327d84e622c61faeb969164bfa370d91e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Aug 2014 23:16:04 +1000 Subject: [PATCH 09/12] drm/nouveau/nvif: fix dac load detect method definition A thinko made me turn this into a u16 when cleaning up. Spotted by coverity. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvif/class.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index cc81e0e5fd30..573491f84792 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h @@ -428,8 +428,8 @@ struct nv50_disp_dac_pwr_v0 { struct nv50_disp_dac_load_v0 { __u8 version; __u8 load; - __u16 data; - __u8 pad04[4]; + __u8 pad02[2]; + __u32 data; }; struct nv50_disp_sor_pwr_v0 { From c9a6fd97335e59a113b53390579379c27fe64ed4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Aug 2014 23:35:35 +1000 Subject: [PATCH 10/12] drm/nouveau: warn if we fail to re-pin fb on resume Spotted by Coverity. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 1cc7b603c753..65b4fd53dd4e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -592,7 +592,9 @@ nouveau_display_repin(struct drm_device *dev) if (!nouveau_fb || !nouveau_fb->nvbo) continue; - nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); + ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); + if (ret) + NV_ERROR(drm, "Could not pin framebuffer\n"); } list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { From 5d6d94f76100e24dfd7a3e20a0f8504f478f52f9 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Tue, 12 Aug 2014 15:16:52 -0700 Subject: [PATCH 11/12] drm/nouveau/gk20a: add LTC device LTC device is now required for PGRAPH to work, add it. Signed-off-by: Alexandre Courbot Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/device/nve0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 54ec53bc6252..cdf9147f32a1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -163,6 +163,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; From 4898ac046d24894d7b2a5a96a1cff4e095844323 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Tue, 12 Aug 2014 15:16:53 -0700 Subject: [PATCH 12/12] drm/nouveau/platform: fix compilation error nouveau_platform.c was still using the old nouveau_dev() macro, triggering a compilation error. Fix this. Signed-off-by: Alexandre Courbot Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 0ffeb50d0088..246a824c16ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c @@ -149,7 +149,8 @@ power_down: static int nouveau_platform_remove(struct platform_device *pdev) { struct drm_device *drm_dev = platform_get_drvdata(pdev); - struct nouveau_device *device = nouveau_dev(drm_dev); + struct nouveau_drm *drm = nouveau_drm(drm_dev); + struct nouveau_device *device = nvkm_device(&drm->device); struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu; nouveau_drm_device_remove(drm_dev);