diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_instmem.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_vm.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_vm.c | 5 |
6 files changed, 22 insertions, 12 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 856d56a98d1e..a76514a209b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -682,6 +682,9 @@ struct drm_nouveau_private { | |||
| 682 | /* For PFIFO and PGRAPH. */ | 682 | /* For PFIFO and PGRAPH. */ |
| 683 | spinlock_t context_switch_lock; | 683 | spinlock_t context_switch_lock; |
| 684 | 684 | ||
| 685 | /* VM/PRAMIN flush, legacy PRAMIN aperture */ | ||
| 686 | spinlock_t vm_lock; | ||
| 687 | |||
| 685 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ | 688 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ |
| 686 | struct nouveau_ramht *ramht; | 689 | struct nouveau_ramht *ramht; |
| 687 | struct nouveau_gpuobj *ramfc; | 690 | struct nouveau_gpuobj *ramfc; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 4f00c87ed86e..67a16e01ffa6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
| @@ -1039,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) | |||
| 1039 | { | 1039 | { |
| 1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; | 1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
| 1041 | struct drm_device *dev = gpuobj->dev; | 1041 | struct drm_device *dev = gpuobj->dev; |
| 1042 | unsigned long flags; | ||
| 1042 | 1043 | ||
| 1043 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { | 1044 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
| 1044 | u64 ptr = gpuobj->vinst + offset; | 1045 | u64 ptr = gpuobj->vinst + offset; |
| 1045 | u32 base = ptr >> 16; | 1046 | u32 base = ptr >> 16; |
| 1046 | u32 val; | 1047 | u32 val; |
| 1047 | 1048 | ||
| 1048 | spin_lock(&dev_priv->ramin_lock); | 1049 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
| 1049 | if (dev_priv->ramin_base != base) { | 1050 | if (dev_priv->ramin_base != base) { |
| 1050 | dev_priv->ramin_base = base; | 1051 | dev_priv->ramin_base = base; |
| 1051 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); | 1052 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
| 1052 | } | 1053 | } |
| 1053 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); | 1054 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); |
| 1054 | spin_unlock(&dev_priv->ramin_lock); | 1055 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
| 1055 | return val; | 1056 | return val; |
| 1056 | } | 1057 | } |
| 1057 | 1058 | ||
| @@ -1063,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) | |||
| 1063 | { | 1064 | { |
| 1064 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; | 1065 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
| 1065 | struct drm_device *dev = gpuobj->dev; | 1066 | struct drm_device *dev = gpuobj->dev; |
| 1067 | unsigned long flags; | ||
| 1066 | 1068 | ||
| 1067 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { | 1069 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
| 1068 | u64 ptr = gpuobj->vinst + offset; | 1070 | u64 ptr = gpuobj->vinst + offset; |
| 1069 | u32 base = ptr >> 16; | 1071 | u32 base = ptr >> 16; |
| 1070 | 1072 | ||
| 1071 | spin_lock(&dev_priv->ramin_lock); | 1073 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
| 1072 | if (dev_priv->ramin_base != base) { | 1074 | if (dev_priv->ramin_base != base) { |
| 1073 | dev_priv->ramin_base = base; | 1075 | dev_priv->ramin_base = base; |
| 1074 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); | 1076 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
| 1075 | } | 1077 | } |
| 1076 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); | 1078 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); |
| 1077 | spin_unlock(&dev_priv->ramin_lock); | 1079 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
| 1078 | return; | 1080 | return; |
| 1079 | } | 1081 | } |
| 1080 | 1082 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 6e2b1a6caa2d..a30adec5beaa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
| @@ -608,6 +608,7 @@ nouveau_card_init(struct drm_device *dev) | |||
| 608 | spin_lock_init(&dev_priv->channels.lock); | 608 | spin_lock_init(&dev_priv->channels.lock); |
| 609 | spin_lock_init(&dev_priv->tile.lock); | 609 | spin_lock_init(&dev_priv->tile.lock); |
| 610 | spin_lock_init(&dev_priv->context_switch_lock); | 610 | spin_lock_init(&dev_priv->context_switch_lock); |
| 611 | spin_lock_init(&dev_priv->vm_lock); | ||
| 611 | 612 | ||
| 612 | /* Make the CRTCs and I2C buses accessible */ | 613 | /* Make the CRTCs and I2C buses accessible */ |
| 613 | ret = engine->display.early_init(dev); | 614 | ret = engine->display.early_init(dev); |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index a6f8aa651fc6..4f95a1e5822e 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
| @@ -404,23 +404,25 @@ void | |||
| 404 | nv50_instmem_flush(struct drm_device *dev) | 404 | nv50_instmem_flush(struct drm_device *dev) |
| 405 | { | 405 | { |
| 406 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 406 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 407 | unsigned long flags; | ||
| 407 | 408 | ||
| 408 | spin_lock(&dev_priv->ramin_lock); | 409 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
| 409 | nv_wr32(dev, 0x00330c, 0x00000001); | 410 | nv_wr32(dev, 0x00330c, 0x00000001); |
| 410 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) | 411 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) |
| 411 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 412 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
| 412 | spin_unlock(&dev_priv->ramin_lock); | 413 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
| 413 | } | 414 | } |
| 414 | 415 | ||
| 415 | void | 416 | void |
| 416 | nv84_instmem_flush(struct drm_device *dev) | 417 | nv84_instmem_flush(struct drm_device *dev) |
| 417 | { | 418 | { |
| 418 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 419 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 420 | unsigned long flags; | ||
| 419 | 421 | ||
| 420 | spin_lock(&dev_priv->ramin_lock); | 422 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
| 421 | nv_wr32(dev, 0x070000, 0x00000001); | 423 | nv_wr32(dev, 0x070000, 0x00000001); |
| 422 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) | 424 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) |
| 423 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 425 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
| 424 | spin_unlock(&dev_priv->ramin_lock); | 426 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
| 425 | } | 427 | } |
| 426 | 428 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 4fd3432b5b8d..6c2694490741 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c | |||
| @@ -174,10 +174,11 @@ void | |||
| 174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) | 174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) |
| 175 | { | 175 | { |
| 176 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 176 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 177 | unsigned long flags; | ||
| 177 | 178 | ||
| 178 | spin_lock(&dev_priv->ramin_lock); | 179 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
| 179 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); | 180 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); |
| 180 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) | 181 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) |
| 181 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); | 182 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); |
| 182 | spin_unlock(&dev_priv->ramin_lock); | 183 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
| 183 | } | 184 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c index a0a2a0277f73..a179e6c55afb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vm.c +++ b/drivers/gpu/drm/nouveau/nvc0_vm.c | |||
| @@ -104,11 +104,12 @@ nvc0_vm_flush(struct nouveau_vm *vm) | |||
| 104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; | 104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; |
| 105 | struct drm_device *dev = vm->dev; | 105 | struct drm_device *dev = vm->dev; |
| 106 | struct nouveau_vm_pgd *vpgd; | 106 | struct nouveau_vm_pgd *vpgd; |
| 107 | unsigned long flags; | ||
| 107 | u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; | 108 | u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; |
| 108 | 109 | ||
| 109 | pinstmem->flush(vm->dev); | 110 | pinstmem->flush(vm->dev); |
| 110 | 111 | ||
| 111 | spin_lock(&dev_priv->ramin_lock); | 112 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
| 112 | list_for_each_entry(vpgd, &vm->pgd_list, head) { | 113 | list_for_each_entry(vpgd, &vm->pgd_list, head) { |
| 113 | /* looks like maybe a "free flush slots" counter, the | 114 | /* looks like maybe a "free flush slots" counter, the |
| 114 | * faster you write to 0x100cbc to more it decreases | 115 | * faster you write to 0x100cbc to more it decreases |
| @@ -125,5 +126,5 @@ nvc0_vm_flush(struct nouveau_vm *vm) | |||
| 125 | nv_rd32(dev, 0x100c80), engine); | 126 | nv_rd32(dev, 0x100c80), engine); |
| 126 | } | 127 | } |
| 127 | } | 128 | } |
| 128 | spin_unlock(&dev_priv->ramin_lock); | 129 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
| 129 | } | 130 | } |
