diff options
author | Dave Airlie <airlied@redhat.com> | 2017-12-18 22:21:11 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-12-18 22:21:11 -0500 |
commit | 51b83e142834638d4fdb4d628ec8602b1107d91b (patch) | |
tree | 8e4290262cfc2f439817e179fb5dd0f03baf8093 | |
parent | 38f73db7683db1ef0b16cb1fedf6e8e309cf08b8 (diff) | |
parent | 74a39954a4900a7dea7010e3063e2bf16b23934b (diff) |
Merge branch 'linux-4.15' of git://github.com/skeggsb/linux into drm-fixes
nouveau regression fixes, and some minor fixes.
* 'linux-4.15' of git://github.com/skeggsb/linux:
drm/nouveau: use alternate memory type for system-memory buffers with kind != 0
drm/nouveau: avoid GPU page sizes > PAGE_SIZE for buffer objects in host memory
drm/nouveau/mmu/gp10b: use correct implementation
drm/nouveau/pci: do a msi rearm on init
drm/nouveau/imem/nv50: fix refcount_t warning
drm/nouveau/bios/dp: support DP Info Table 2.0
drm/nouveau/fbcon: fix NULL pointer access in nouveau_fbcon_destroy
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mem.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_ttm.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | 7 |
9 files changed, 62 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2615912430cc..435ff8662cfa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -224,7 +224,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
224 | /* Determine if we can get a cache-coherent map, forcing | 224 | /* Determine if we can get a cache-coherent map, forcing |
225 | * uncached mapping if we can't. | 225 | * uncached mapping if we can't. |
226 | */ | 226 | */ |
227 | if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | 227 | if (!nouveau_drm_use_coherent_gpu_mapping(drm)) |
228 | nvbo->force_coherent = true; | 228 | nvbo->force_coherent = true; |
229 | } | 229 | } |
230 | 230 | ||
@@ -262,7 +262,8 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && | 262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && |
263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) | 263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) |
264 | continue; | 264 | continue; |
265 | if ((flags & TTM_PL_FLAG_TT ) && !vmm->page[i].host) | 265 | if ((flags & TTM_PL_FLAG_TT) && |
266 | (!vmm->page[i].host || vmm->page[i].shift > PAGE_SHIFT)) | ||
266 | continue; | 267 | continue; |
267 | 268 | ||
268 | /* Select this page size if it's the first that supports | 269 | /* Select this page size if it's the first that supports |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3331e82ae9e7..96f6bd8aee5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -157,8 +157,8 @@ struct nouveau_drm { | |||
157 | struct nvif_object copy; | 157 | struct nvif_object copy; |
158 | int mtrr; | 158 | int mtrr; |
159 | int type_vram; | 159 | int type_vram; |
160 | int type_host; | 160 | int type_host[2]; |
161 | int type_ncoh; | 161 | int type_ncoh[2]; |
162 | } ttm; | 162 | } ttm; |
163 | 163 | ||
164 | /* GEM interface support */ | 164 | /* GEM interface support */ |
@@ -217,6 +217,13 @@ nouveau_drm(struct drm_device *dev) | |||
217 | return dev->dev_private; | 217 | return dev->dev_private; |
218 | } | 218 | } |
219 | 219 | ||
220 | static inline bool | ||
221 | nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm) | ||
222 | { | ||
223 | struct nvif_mmu *mmu = &drm->client.mmu; | ||
224 | return !(mmu->type[drm->ttm.type_host[0]].type & NVIF_MEM_UNCACHED); | ||
225 | } | ||
226 | |||
220 | int nouveau_pmops_suspend(struct device *); | 227 | int nouveau_pmops_suspend(struct device *); |
221 | int nouveau_pmops_resume(struct device *); | 228 | int nouveau_pmops_resume(struct device *); |
222 | bool nouveau_pmops_runtime(void); | 229 | bool nouveau_pmops_runtime(void); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index c533d8e04afc..be7357bf2246 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -429,7 +429,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) | |||
429 | drm_fb_helper_unregister_fbi(&fbcon->helper); | 429 | drm_fb_helper_unregister_fbi(&fbcon->helper); |
430 | drm_fb_helper_fini(&fbcon->helper); | 430 | drm_fb_helper_fini(&fbcon->helper); |
431 | 431 | ||
432 | if (nouveau_fb->nvbo) { | 432 | if (nouveau_fb && nouveau_fb->nvbo) { |
433 | nouveau_vma_del(&nouveau_fb->vma); | 433 | nouveau_vma_del(&nouveau_fb->vma); |
434 | nouveau_bo_unmap(nouveau_fb->nvbo); | 434 | nouveau_bo_unmap(nouveau_fb->nvbo); |
435 | nouveau_bo_unpin(nouveau_fb->nvbo); | 435 | nouveau_bo_unpin(nouveau_fb->nvbo); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 589a9621db76..c002f8968507 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -103,10 +103,10 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) | |||
103 | u8 type; | 103 | u8 type; |
104 | int ret; | 104 | int ret; |
105 | 105 | ||
106 | if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | 106 | if (!nouveau_drm_use_coherent_gpu_mapping(drm)) |
107 | type = drm->ttm.type_ncoh; | 107 | type = drm->ttm.type_ncoh[!!mem->kind]; |
108 | else | 108 | else |
109 | type = drm->ttm.type_host; | 109 | type = drm->ttm.type_host[0]; |
110 | 110 | ||
111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) | 111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) |
112 | mem->comp = mem->kind = 0; | 112 | mem->comp = mem->kind = 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 08b974b30482..dff51a0ee028 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
@@ -235,27 +235,46 @@ nouveau_ttm_global_release(struct nouveau_drm *drm) | |||
235 | drm->ttm.mem_global_ref.release = NULL; | 235 | drm->ttm.mem_global_ref.release = NULL; |
236 | } | 236 | } |
237 | 237 | ||
238 | int | 238 | static int |
239 | nouveau_ttm_init(struct nouveau_drm *drm) | 239 | nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind) |
240 | { | 240 | { |
241 | struct nvkm_device *device = nvxx_device(&drm->client.device); | ||
242 | struct nvkm_pci *pci = device->pci; | ||
243 | struct nvif_mmu *mmu = &drm->client.mmu; | 241 | struct nvif_mmu *mmu = &drm->client.mmu; |
244 | struct drm_device *dev = drm->dev; | 242 | int typei; |
245 | int typei, ret; | ||
246 | 243 | ||
247 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | | 244 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | |
248 | NVIF_MEM_COHERENT); | 245 | kind | NVIF_MEM_COHERENT); |
249 | if (typei < 0) | 246 | if (typei < 0) |
250 | return -ENOSYS; | 247 | return -ENOSYS; |
251 | 248 | ||
252 | drm->ttm.type_host = typei; | 249 | drm->ttm.type_host[!!kind] = typei; |
253 | 250 | ||
254 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE); | 251 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | kind); |
255 | if (typei < 0) | 252 | if (typei < 0) |
256 | return -ENOSYS; | 253 | return -ENOSYS; |
257 | 254 | ||
258 | drm->ttm.type_ncoh = typei; | 255 | drm->ttm.type_ncoh[!!kind] = typei; |
256 | return 0; | ||
257 | } | ||
258 | |||
259 | int | ||
260 | nouveau_ttm_init(struct nouveau_drm *drm) | ||
261 | { | ||
262 | struct nvkm_device *device = nvxx_device(&drm->client.device); | ||
263 | struct nvkm_pci *pci = device->pci; | ||
264 | struct nvif_mmu *mmu = &drm->client.mmu; | ||
265 | struct drm_device *dev = drm->dev; | ||
266 | int typei, ret; | ||
267 | |||
268 | ret = nouveau_ttm_init_host(drm, 0); | ||
269 | if (ret) | ||
270 | return ret; | ||
271 | |||
272 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA && | ||
273 | drm->client.device.info.chipset != 0x50) { | ||
274 | ret = nouveau_ttm_init_host(drm, NVIF_MEM_KIND); | ||
275 | if (ret) | ||
276 | return ret; | ||
277 | } | ||
259 | 278 | ||
260 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && | 279 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && |
261 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { | 280 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index e14643615698..00eeaaffeae5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |||
@@ -2369,7 +2369,7 @@ nv13b_chipset = { | |||
2369 | .imem = gk20a_instmem_new, | 2369 | .imem = gk20a_instmem_new, |
2370 | .ltc = gp100_ltc_new, | 2370 | .ltc = gp100_ltc_new, |
2371 | .mc = gp10b_mc_new, | 2371 | .mc = gp10b_mc_new, |
2372 | .mmu = gf100_mmu_new, | 2372 | .mmu = gp10b_mmu_new, |
2373 | .secboot = gp10b_secboot_new, | 2373 | .secboot = gp10b_secboot_new, |
2374 | .pmu = gm20b_pmu_new, | 2374 | .pmu = gm20b_pmu_new, |
2375 | .timer = gk20a_timer_new, | 2375 | .timer = gk20a_timer_new, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c index 972370ed36f0..7c7efa4ea0d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c | |||
@@ -36,6 +36,7 @@ nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
36 | if (data) { | 36 | if (data) { |
37 | *ver = nvbios_rd08(bios, data + 0x00); | 37 | *ver = nvbios_rd08(bios, data + 0x00); |
38 | switch (*ver) { | 38 | switch (*ver) { |
39 | case 0x20: | ||
39 | case 0x21: | 40 | case 0x21: |
40 | case 0x30: | 41 | case 0x30: |
41 | case 0x40: | 42 | case 0x40: |
@@ -63,6 +64,7 @@ nvbios_dpout_entry(struct nvkm_bios *bios, u8 idx, | |||
63 | if (data && idx < *cnt) { | 64 | if (data && idx < *cnt) { |
64 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); | 65 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); |
65 | switch (*ver * !!outp) { | 66 | switch (*ver * !!outp) { |
67 | case 0x20: | ||
66 | case 0x21: | 68 | case 0x21: |
67 | case 0x30: | 69 | case 0x30: |
68 | *hdr = nvbios_rd08(bios, data + 0x04); | 70 | *hdr = nvbios_rd08(bios, data + 0x04); |
@@ -96,12 +98,16 @@ nvbios_dpout_parse(struct nvkm_bios *bios, u8 idx, | |||
96 | info->type = nvbios_rd16(bios, data + 0x00); | 98 | info->type = nvbios_rd16(bios, data + 0x00); |
97 | info->mask = nvbios_rd16(bios, data + 0x02); | 99 | info->mask = nvbios_rd16(bios, data + 0x02); |
98 | switch (*ver) { | 100 | switch (*ver) { |
101 | case 0x20: | ||
102 | info->mask |= 0x00c0; /* match any link */ | ||
103 | /* fall-through */ | ||
99 | case 0x21: | 104 | case 0x21: |
100 | case 0x30: | 105 | case 0x30: |
101 | info->flags = nvbios_rd08(bios, data + 0x05); | 106 | info->flags = nvbios_rd08(bios, data + 0x05); |
102 | info->script[0] = nvbios_rd16(bios, data + 0x06); | 107 | info->script[0] = nvbios_rd16(bios, data + 0x06); |
103 | info->script[1] = nvbios_rd16(bios, data + 0x08); | 108 | info->script[1] = nvbios_rd16(bios, data + 0x08); |
104 | info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | 109 | if (*len >= 0x0c) |
110 | info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | ||
105 | if (*len >= 0x0f) { | 111 | if (*len >= 0x0f) { |
106 | info->script[2] = nvbios_rd16(bios, data + 0x0c); | 112 | info->script[2] = nvbios_rd16(bios, data + 0x0c); |
107 | info->script[3] = nvbios_rd16(bios, data + 0x0e); | 113 | info->script[3] = nvbios_rd16(bios, data + 0x0e); |
@@ -170,6 +176,7 @@ nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
170 | memset(info, 0x00, sizeof(*info)); | 176 | memset(info, 0x00, sizeof(*info)); |
171 | if (data) { | 177 | if (data) { |
172 | switch (*ver) { | 178 | switch (*ver) { |
179 | case 0x20: | ||
173 | case 0x21: | 180 | case 0x21: |
174 | info->dc = nvbios_rd08(bios, data + 0x02); | 181 | info->dc = nvbios_rd08(bios, data + 0x02); |
175 | info->pe = nvbios_rd08(bios, data + 0x03); | 182 | info->pe = nvbios_rd08(bios, data + 0x03); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 1ba7289684aa..db48a1daca0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | |||
@@ -249,7 +249,7 @@ nv50_instobj_acquire(struct nvkm_memory *memory) | |||
249 | iobj->base.memory.ptrs = &nv50_instobj_fast; | 249 | iobj->base.memory.ptrs = &nv50_instobj_fast; |
250 | else | 250 | else |
251 | iobj->base.memory.ptrs = &nv50_instobj_slow; | 251 | iobj->base.memory.ptrs = &nv50_instobj_slow; |
252 | refcount_inc(&iobj->maps); | 252 | refcount_set(&iobj->maps, 1); |
253 | } | 253 | } |
254 | 254 | ||
255 | mutex_unlock(&imem->subdev.mutex); | 255 | mutex_unlock(&imem->subdev.mutex); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index b1b1f3626b96..deb96de54b00 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | |||
@@ -136,6 +136,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev) | |||
136 | return ret; | 136 | return ret; |
137 | 137 | ||
138 | pci->irq = pdev->irq; | 138 | pci->irq = pdev->irq; |
139 | |||
140 | /* Ensure MSI interrupts are armed, for the case where there are | ||
141 | * already interrupts pending (for whatever reason) at load time. | ||
142 | */ | ||
143 | if (pci->msi) | ||
144 | pci->func->msi_rearm(pci); | ||
145 | |||
139 | return ret; | 146 | return ret; |
140 | } | 147 | } |
141 | 148 | ||