diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/xtensa.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/vm.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/fb/priv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c | 22 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/vm/base.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv17_fence.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_fence.c | 14 |
17 files changed, 79 insertions, 56 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c index 373dbcc523b2..a19e7d79b847 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c | |||
| @@ -36,6 +36,8 @@ nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | |||
| 36 | if (data && data[0]) { | 36 | if (data && data[0]) { |
| 37 | for (i = 0; i < size; i++) | 37 | for (i = 0; i < size; i++) |
| 38 | nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]); | 38 | nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]); |
| 39 | for (; i < 0x60; i++) | ||
| 40 | nv_wr32(priv, 0x61c440 + soff, (i << 8)); | ||
| 39 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); | 41 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); |
| 40 | } else | 42 | } else |
| 41 | if (data) { | 43 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c index dc57e24fc1df..717639386ced 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c | |||
| @@ -41,6 +41,8 @@ nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | |||
| 41 | if (data && data[0]) { | 41 | if (data && data[0]) { |
| 42 | for (i = 0; i < size; i++) | 42 | for (i = 0; i < size; i++) |
| 43 | nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); | 43 | nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); |
| 44 | for (; i < 0x60; i++) | ||
| 45 | nv_wr32(priv, 0x10ec00 + soff, (i << 8)); | ||
| 44 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); | 46 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); |
| 45 | } else | 47 | } else |
| 46 | if (data) { | 48 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index ab1e918469a8..526b75242899 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | |||
| @@ -47,14 +47,8 @@ int | |||
| 47 | nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | 47 | nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) |
| 48 | { | 48 | { |
| 49 | struct nv50_disp_priv *priv = (void *)object->engine; | 49 | struct nv50_disp_priv *priv = (void *)object->engine; |
| 50 | struct nouveau_bios *bios = nouveau_bios(priv); | ||
| 51 | const u16 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12; | ||
| 52 | const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3; | 50 | const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3; |
| 53 | const u8 link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2; | ||
| 54 | const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR); | 51 | const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR); |
| 55 | const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or); | ||
| 56 | struct dcb_output outp; | ||
| 57 | u8 ver, hdr; | ||
| 58 | u32 data; | 52 | u32 data; |
| 59 | int ret = -EINVAL; | 53 | int ret = -EINVAL; |
| 60 | 54 | ||
| @@ -62,8 +56,6 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | |||
| 62 | return -EINVAL; | 56 | return -EINVAL; |
| 63 | data = *(u32 *)args; | 57 | data = *(u32 *)args; |
| 64 | 58 | ||
| 65 | if (type && !dcb_outp_match(bios, type, mask, &ver, &hdr, &outp)) | ||
| 66 | return -ENODEV; | ||
| 67 | 59 | ||
| 68 | switch (mthd & ~0x3f) { | 60 | switch (mthd & ~0x3f) { |
| 69 | case NV50_DISP_SOR_PWR: | 61 | case NV50_DISP_SOR_PWR: |
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c index 49ecbb859b25..c19004301309 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | |||
| @@ -265,8 +265,8 @@ nv31_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 265 | int | 265 | int |
| 266 | nv31_mpeg_init(struct nouveau_object *object) | 266 | nv31_mpeg_init(struct nouveau_object *object) |
| 267 | { | 267 | { |
| 268 | struct nouveau_engine *engine = nv_engine(object->engine); | 268 | struct nouveau_engine *engine = nv_engine(object); |
| 269 | struct nv31_mpeg_priv *priv = (void *)engine; | 269 | struct nv31_mpeg_priv *priv = (void *)object; |
| 270 | struct nouveau_fb *pfb = nouveau_fb(object); | 270 | struct nouveau_fb *pfb = nouveau_fb(object); |
| 271 | int ret, i; | 271 | int ret, i; |
| 272 | 272 | ||
| @@ -284,7 +284,10 @@ nv31_mpeg_init(struct nouveau_object *object) | |||
| 284 | /* PMPEG init */ | 284 | /* PMPEG init */ |
| 285 | nv_wr32(priv, 0x00b32c, 0x00000000); | 285 | nv_wr32(priv, 0x00b32c, 0x00000000); |
| 286 | nv_wr32(priv, 0x00b314, 0x00000100); | 286 | nv_wr32(priv, 0x00b314, 0x00000100); |
| 287 | nv_wr32(priv, 0x00b220, nv44_graph_class(priv) ? 0x00000044 : 0x00000031); | 287 | if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv)) |
| 288 | nv_wr32(priv, 0x00b220, 0x00000044); | ||
| 289 | else | ||
| 290 | nv_wr32(priv, 0x00b220, 0x00000031); | ||
| 288 | nv_wr32(priv, 0x00b300, 0x02001ec1); | 291 | nv_wr32(priv, 0x00b300, 0x02001ec1); |
| 289 | nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); | 292 | nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); |
| 290 | 293 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index f7c581ad1991..dd6196072e9c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c | |||
| @@ -61,6 +61,7 @@ nv40_mpeg_context_ctor(struct nouveau_object *parent, | |||
| 61 | if (ret) | 61 | if (ret) |
| 62 | return ret; | 62 | return ret; |
| 63 | 63 | ||
| 64 | nv_wo32(&chan->base.base, 0x78, 0x02001ec1); | ||
| 64 | return 0; | 65 | return 0; |
| 65 | } | 66 | } |
| 66 | 67 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/xtensa.c b/drivers/gpu/drm/nouveau/core/engine/xtensa.c index 0639bc59d0a5..5f6ede7c4892 100644 --- a/drivers/gpu/drm/nouveau/core/engine/xtensa.c +++ b/drivers/gpu/drm/nouveau/core/engine/xtensa.c | |||
| @@ -118,7 +118,13 @@ _nouveau_xtensa_init(struct nouveau_object *object) | |||
| 118 | return ret; | 118 | return ret; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | ret = nouveau_gpuobj_new(object, NULL, fw->size, 0x1000, 0, | 121 | if (fw->size > 0x40000) { |
| 122 | nv_warn(xtensa, "firmware %s too large\n", name); | ||
| 123 | release_firmware(fw); | ||
| 124 | return -EINVAL; | ||
| 125 | } | ||
| 126 | |||
| 127 | ret = nouveau_gpuobj_new(object, NULL, 0x40000, 0x1000, 0, | ||
| 122 | &xtensa->gpu_fw); | 128 | &xtensa->gpu_fw); |
| 123 | if (ret) { | 129 | if (ret) { |
| 124 | release_firmware(fw); | 130 | release_firmware(fw); |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h index f2e87b105666..fcf57fa309bf 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h | |||
| @@ -55,7 +55,7 @@ struct nouveau_vma { | |||
| 55 | struct nouveau_vm { | 55 | struct nouveau_vm { |
| 56 | struct nouveau_vmmgr *vmm; | 56 | struct nouveau_vmmgr *vmm; |
| 57 | struct nouveau_mm mm; | 57 | struct nouveau_mm mm; |
| 58 | int refcount; | 58 | struct kref refcount; |
| 59 | 59 | ||
| 60 | struct list_head pgd_list; | 60 | struct list_head pgd_list; |
| 61 | atomic_t engref[NVDEV_SUBDEV_NR]; | 61 | atomic_t engref[NVDEV_SUBDEV_NR]; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h index 6c974dd83e8b..db9d6ddde52c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h | |||
| @@ -81,7 +81,7 @@ void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); | |||
| 81 | void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, | 81 | void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, |
| 82 | u32 pitch, u32 flags, struct nouveau_fb_tile *); | 82 | u32 pitch, u32 flags, struct nouveau_fb_tile *); |
| 83 | 83 | ||
| 84 | void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **); | 84 | void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *); |
| 85 | extern int nv50_fb_memtype[0x80]; | 85 | extern int nv50_fb_memtype[0x80]; |
| 86 | 86 | ||
| 87 | #endif | 87 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c index af5aa7ee8ad9..903baff77fdd 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c | |||
| @@ -27,17 +27,10 @@ | |||
| 27 | #include "priv.h" | 27 | #include "priv.h" |
| 28 | 28 | ||
| 29 | void | 29 | void |
| 30 | nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | 30 | __nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem) |
| 31 | { | 31 | { |
| 32 | struct nouveau_mm_node *this; | 32 | struct nouveau_mm_node *this; |
| 33 | struct nouveau_mem *mem; | ||
| 34 | 33 | ||
| 35 | mem = *pmem; | ||
| 36 | *pmem = NULL; | ||
| 37 | if (unlikely(mem == NULL)) | ||
| 38 | return; | ||
| 39 | |||
| 40 | mutex_lock(&pfb->base.mutex); | ||
| 41 | while (!list_empty(&mem->regions)) { | 34 | while (!list_empty(&mem->regions)) { |
| 42 | this = list_first_entry(&mem->regions, typeof(*this), rl_entry); | 35 | this = list_first_entry(&mem->regions, typeof(*this), rl_entry); |
| 43 | 36 | ||
| @@ -46,6 +39,19 @@ nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | |||
| 46 | } | 39 | } |
| 47 | 40 | ||
| 48 | nouveau_mm_free(&pfb->tags, &mem->tag); | 41 | nouveau_mm_free(&pfb->tags, &mem->tag); |
| 42 | } | ||
| 43 | |||
| 44 | void | ||
| 45 | nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | ||
| 46 | { | ||
| 47 | struct nouveau_mem *mem = *pmem; | ||
| 48 | |||
| 49 | *pmem = NULL; | ||
| 50 | if (unlikely(mem == NULL)) | ||
| 51 | return; | ||
| 52 | |||
| 53 | mutex_lock(&pfb->base.mutex); | ||
| 54 | __nv50_ram_put(pfb, mem); | ||
| 49 | mutex_unlock(&pfb->base.mutex); | 55 | mutex_unlock(&pfb->base.mutex); |
| 50 | 56 | ||
| 51 | kfree(mem); | 57 | kfree(mem); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c index 9c3634acbb9d..cf97c4de4a6b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c | |||
| @@ -33,11 +33,19 @@ void | |||
| 33 | nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | 33 | nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) |
| 34 | { | 34 | { |
| 35 | struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb); | 35 | struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb); |
| 36 | struct nouveau_mem *mem = *pmem; | ||
| 36 | 37 | ||
| 37 | if ((*pmem)->tag) | 38 | *pmem = NULL; |
| 38 | ltcg->tags_free(ltcg, &(*pmem)->tag); | 39 | if (unlikely(mem == NULL)) |
| 40 | return; | ||
| 39 | 41 | ||
| 40 | nv50_ram_put(pfb, pmem); | 42 | mutex_lock(&pfb->base.mutex); |
| 43 | if (mem->tag) | ||
| 44 | ltcg->tags_free(ltcg, &mem->tag); | ||
| 45 | __nv50_ram_put(pfb, mem); | ||
| 46 | mutex_unlock(&pfb->base.mutex); | ||
| 47 | |||
| 48 | kfree(mem); | ||
| 41 | } | 49 | } |
| 42 | 50 | ||
| 43 | int | 51 | int |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c index bf489dcf46e2..c4c1d415e7fe 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c | |||
| @@ -103,7 +103,7 @@ nv50_gpio_intr(struct nouveau_subdev *subdev) | |||
| 103 | int i; | 103 | int i; |
| 104 | 104 | ||
| 105 | intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050); | 105 | intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050); |
| 106 | if (nv_device(priv)->chipset >= 0x90) | 106 | if (nv_device(priv)->chipset > 0x92) |
| 107 | intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070); | 107 | intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070); |
| 108 | 108 | ||
| 109 | hi = (intr0 & 0x0000ffff) | (intr1 << 16); | 109 | hi = (intr0 & 0x0000ffff) | (intr1 << 16); |
| @@ -115,7 +115,7 @@ nv50_gpio_intr(struct nouveau_subdev *subdev) | |||
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | nv_wr32(priv, 0xe054, intr0); | 117 | nv_wr32(priv, 0xe054, intr0); |
| 118 | if (nv_device(priv)->chipset >= 0x90) | 118 | if (nv_device(priv)->chipset > 0x92) |
| 119 | nv_wr32(priv, 0xe074, intr1); | 119 | nv_wr32(priv, 0xe074, intr1); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| @@ -146,7 +146,7 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 146 | int ret; | 146 | int ret; |
| 147 | 147 | ||
| 148 | ret = nouveau_gpio_create(parent, engine, oclass, | 148 | ret = nouveau_gpio_create(parent, engine, oclass, |
| 149 | nv_device(parent)->chipset >= 0x90 ? 32 : 16, | 149 | nv_device(parent)->chipset > 0x92 ? 32 : 16, |
| 150 | &priv); | 150 | &priv); |
| 151 | *pobject = nv_object(priv); | 151 | *pobject = nv_object(priv); |
| 152 | if (ret) | 152 | if (ret) |
| @@ -182,7 +182,7 @@ nv50_gpio_init(struct nouveau_object *object) | |||
| 182 | /* disable, and ack any pending gpio interrupts */ | 182 | /* disable, and ack any pending gpio interrupts */ |
| 183 | nv_wr32(priv, 0xe050, 0x00000000); | 183 | nv_wr32(priv, 0xe050, 0x00000000); |
| 184 | nv_wr32(priv, 0xe054, 0xffffffff); | 184 | nv_wr32(priv, 0xe054, 0xffffffff); |
| 185 | if (nv_device(priv)->chipset >= 0x90) { | 185 | if (nv_device(priv)->chipset > 0x92) { |
| 186 | nv_wr32(priv, 0xe070, 0x00000000); | 186 | nv_wr32(priv, 0xe070, 0x00000000); |
| 187 | nv_wr32(priv, 0xe074, 0xffffffff); | 187 | nv_wr32(priv, 0xe074, 0xffffffff); |
| 188 | } | 188 | } |
| @@ -195,7 +195,7 @@ nv50_gpio_fini(struct nouveau_object *object, bool suspend) | |||
| 195 | { | 195 | { |
| 196 | struct nv50_gpio_priv *priv = (void *)object; | 196 | struct nv50_gpio_priv *priv = (void *)object; |
| 197 | nv_wr32(priv, 0xe050, 0x00000000); | 197 | nv_wr32(priv, 0xe050, 0x00000000); |
| 198 | if (nv_device(priv)->chipset >= 0x90) | 198 | if (nv_device(priv)->chipset > 0x92) |
| 199 | nv_wr32(priv, 0xe070, 0x00000000); | 199 | nv_wr32(priv, 0xe070, 0x00000000); |
| 200 | return nouveau_gpio_fini(&priv->base, suspend); | 200 | return nouveau_gpio_fini(&priv->base, suspend); |
| 201 | } | 201 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index 0cb322a5e72c..f25fc5fc7dd1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c | |||
| @@ -41,7 +41,7 @@ nv50_mc_intr[] = { | |||
| 41 | { 0x04000000, NVDEV_ENGINE_DISP }, | 41 | { 0x04000000, NVDEV_ENGINE_DISP }, |
| 42 | { 0x10000000, NVDEV_SUBDEV_BUS }, | 42 | { 0x10000000, NVDEV_SUBDEV_BUS }, |
| 43 | { 0x80000000, NVDEV_ENGINE_SW }, | 43 | { 0x80000000, NVDEV_ENGINE_SW }, |
| 44 | { 0x0000d101, NVDEV_SUBDEV_FB }, | 44 | { 0x0002d101, NVDEV_SUBDEV_FB }, |
| 45 | {}, | 45 | {}, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c index 67fcb6c852ac..ef3133e7575c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c | |||
| @@ -361,7 +361,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, | |||
| 361 | 361 | ||
| 362 | INIT_LIST_HEAD(&vm->pgd_list); | 362 | INIT_LIST_HEAD(&vm->pgd_list); |
| 363 | vm->vmm = vmm; | 363 | vm->vmm = vmm; |
| 364 | vm->refcount = 1; | 364 | kref_init(&vm->refcount); |
| 365 | vm->fpde = offset >> (vmm->pgt_bits + 12); | 365 | vm->fpde = offset >> (vmm->pgt_bits + 12); |
| 366 | vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12); | 366 | vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12); |
| 367 | 367 | ||
| @@ -441,8 +441,9 @@ nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd) | |||
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | static void | 443 | static void |
| 444 | nouveau_vm_del(struct nouveau_vm *vm) | 444 | nouveau_vm_del(struct kref *kref) |
| 445 | { | 445 | { |
| 446 | struct nouveau_vm *vm = container_of(kref, typeof(*vm), refcount); | ||
| 446 | struct nouveau_vm_pgd *vpgd, *tmp; | 447 | struct nouveau_vm_pgd *vpgd, *tmp; |
| 447 | 448 | ||
| 448 | list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { | 449 | list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { |
| @@ -458,27 +459,19 @@ int | |||
| 458 | nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, | 459 | nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, |
| 459 | struct nouveau_gpuobj *pgd) | 460 | struct nouveau_gpuobj *pgd) |
| 460 | { | 461 | { |
| 461 | struct nouveau_vm *vm; | 462 | if (ref) { |
| 462 | int ret; | 463 | int ret = nouveau_vm_link(ref, pgd); |
| 463 | |||
| 464 | vm = ref; | ||
| 465 | if (vm) { | ||
| 466 | ret = nouveau_vm_link(vm, pgd); | ||
| 467 | if (ret) | 464 | if (ret) |
| 468 | return ret; | 465 | return ret; |
| 469 | 466 | ||
| 470 | vm->refcount++; | 467 | kref_get(&ref->refcount); |
| 471 | } | 468 | } |
| 472 | 469 | ||
| 473 | vm = *ptr; | 470 | if (*ptr) { |
| 474 | *ptr = ref; | 471 | nouveau_vm_unlink(*ptr, pgd); |
| 475 | 472 | kref_put(&(*ptr)->refcount, nouveau_vm_del); | |
| 476 | if (vm) { | ||
| 477 | nouveau_vm_unlink(vm, pgd); | ||
| 478 | |||
| 479 | if (--vm->refcount == 0) | ||
| 480 | nouveau_vm_del(vm); | ||
| 481 | } | 473 | } |
| 482 | 474 | ||
| 475 | *ptr = ref; | ||
| 483 | return 0; | 476 | return 0; |
| 484 | } | 477 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 4e7ee5f4155c..af20fba3a1a4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -198,7 +198,12 @@ nouveau_bo_new(struct drm_device *dev, int size, int align, | |||
| 198 | size_t acc_size; | 198 | size_t acc_size; |
| 199 | int ret; | 199 | int ret; |
| 200 | int type = ttm_bo_type_device; | 200 | int type = ttm_bo_type_device; |
| 201 | int max_size = INT_MAX & ~((1 << drm->client.base.vm->vmm->lpg_shift) - 1); | 201 | int lpg_shift = 12; |
| 202 | int max_size; | ||
| 203 | |||
| 204 | if (drm->client.base.vm) | ||
| 205 | lpg_shift = drm->client.base.vm->vmm->lpg_shift; | ||
| 206 | max_size = INT_MAX & ~((1 << lpg_shift) - 1); | ||
| 202 | 207 | ||
| 203 | if (size <= 0 || size > max_size) { | 208 | if (size <= 0 || size > max_size) { |
| 204 | nv_warn(drm, "skipped size %x\n", (u32)size); | 209 | nv_warn(drm, "skipped size %x\n", (u32)size); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 4c1bc061fae2..8f6d63d7edd3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
| @@ -398,7 +398,8 @@ void | |||
| 398 | nouveau_fbcon_output_poll_changed(struct drm_device *dev) | 398 | nouveau_fbcon_output_poll_changed(struct drm_device *dev) |
| 399 | { | 399 | { |
| 400 | struct nouveau_drm *drm = nouveau_drm(dev); | 400 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 401 | drm_fb_helper_hotplug_event(&drm->fbcon->helper); | 401 | if (drm->fbcon) |
| 402 | drm_fb_helper_hotplug_event(&drm->fbcon->helper); | ||
| 402 | } | 403 | } |
| 403 | 404 | ||
| 404 | static int | 405 | static int |
diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 8e47a9bae8c3..22aa9963ea6f 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c | |||
| @@ -76,7 +76,7 @@ nv17_fence_context_new(struct nouveau_channel *chan) | |||
| 76 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; | 76 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; |
| 77 | struct nouveau_object *object; | 77 | struct nouveau_object *object; |
| 78 | u32 start = mem->start * PAGE_SIZE; | 78 | u32 start = mem->start * PAGE_SIZE; |
| 79 | u32 limit = mem->start + mem->size - 1; | 79 | u32 limit = start + mem->size - 1; |
| 80 | int ret = 0; | 80 | int ret = 0; |
| 81 | 81 | ||
| 82 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); | 82 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index f9701e567db8..0ee363840035 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c | |||
| @@ -39,6 +39,8 @@ nv50_fence_context_new(struct nouveau_channel *chan) | |||
| 39 | struct nv10_fence_chan *fctx; | 39 | struct nv10_fence_chan *fctx; |
| 40 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; | 40 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; |
| 41 | struct nouveau_object *object; | 41 | struct nouveau_object *object; |
| 42 | u32 start = mem->start * PAGE_SIZE; | ||
| 43 | u32 limit = start + mem->size - 1; | ||
| 42 | int ret, i; | 44 | int ret, i; |
| 43 | 45 | ||
| 44 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); | 46 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); |
| @@ -51,26 +53,28 @@ nv50_fence_context_new(struct nouveau_channel *chan) | |||
| 51 | fctx->base.sync = nv17_fence_sync; | 53 | fctx->base.sync = nv17_fence_sync; |
| 52 | 54 | ||
| 53 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, | 55 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, |
| 54 | NvSema, 0x0002, | 56 | NvSema, 0x003d, |
| 55 | &(struct nv_dma_class) { | 57 | &(struct nv_dma_class) { |
| 56 | .flags = NV_DMA_TARGET_VRAM | | 58 | .flags = NV_DMA_TARGET_VRAM | |
| 57 | NV_DMA_ACCESS_RDWR, | 59 | NV_DMA_ACCESS_RDWR, |
| 58 | .start = mem->start * PAGE_SIZE, | 60 | .start = start, |
| 59 | .limit = mem->size - 1, | 61 | .limit = limit, |
| 60 | }, sizeof(struct nv_dma_class), | 62 | }, sizeof(struct nv_dma_class), |
| 61 | &object); | 63 | &object); |
| 62 | 64 | ||
| 63 | /* dma objects for display sync channel semaphore blocks */ | 65 | /* dma objects for display sync channel semaphore blocks */ |
| 64 | for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { | 66 | for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { |
| 65 | struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); | 67 | struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); |
| 68 | u32 start = bo->bo.mem.start * PAGE_SIZE; | ||
| 69 | u32 limit = start + bo->bo.mem.size - 1; | ||
| 66 | 70 | ||
| 67 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, | 71 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, |
| 68 | NvEvoSema0 + i, 0x003d, | 72 | NvEvoSema0 + i, 0x003d, |
| 69 | &(struct nv_dma_class) { | 73 | &(struct nv_dma_class) { |
| 70 | .flags = NV_DMA_TARGET_VRAM | | 74 | .flags = NV_DMA_TARGET_VRAM | |
| 71 | NV_DMA_ACCESS_RDWR, | 75 | NV_DMA_ACCESS_RDWR, |
| 72 | .start = bo->bo.offset, | 76 | .start = start, |
| 73 | .limit = bo->bo.offset + 0xfff, | 77 | .limit = limit, |
| 74 | }, sizeof(struct nv_dma_class), | 78 | }, sizeof(struct nv_dma_class), |
| 75 | &object); | 79 | &object); |
| 76 | } | 80 | } |
