mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 08:58:02 +02:00
nouveau: hide instmem map, force use of {prepare,finish}_access
This commit is contained in:
parent
cdba1bf2e4
commit
afac6a4ddc
16 changed files with 188 additions and 22 deletions
|
|
@ -105,11 +105,13 @@ nouveau_sgdma_bind(struct drm_ttm_backend *be, struct drm_bo_mem_reg *mem)
|
|||
if (dev_priv->card_type < NV_50)
|
||||
nvbe->pte_start += 2; /* skip ctxdma header */
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
|
||||
for (i = nvbe->pte_start; i < nvbe->pte_start + nvbe->pages; i++) {
|
||||
uint64_t pteval = nvbe->pagelist[i - nvbe->pte_start];
|
||||
|
||||
if (pteval & NV_CTXDMA_PAGE_MASK) {
|
||||
DRM_ERROR("Bad pteval 0x%llx\n", pteval);
|
||||
dev_priv->engine.instmem.finish_access(nvbe->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +131,7 @@ nouveau_sgdma_bind(struct drm_ttm_backend *be, struct drm_bo_mem_reg *mem)
|
|||
INSTANCE_WR(gpuobj, (i<<1)+1, tile);
|
||||
}
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(nvbe->dev);
|
||||
|
||||
nvbe->is_bound = 1;
|
||||
return 0;
|
||||
|
|
@ -146,6 +149,7 @@ nouveau_sgdma_unbind(struct drm_ttm_backend *be)
|
|||
struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
|
||||
unsigned int pte;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
|
||||
pte = nvbe->pte_start;
|
||||
while (pte < (nvbe->pte_start + nvbe->pages)) {
|
||||
uint64_t pteval = dev_priv->gart_info.sg_dummy_bus;
|
||||
|
|
@ -159,6 +163,7 @@ nouveau_sgdma_unbind(struct drm_ttm_backend *be)
|
|||
|
||||
pte++;
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(nvbe->dev);
|
||||
|
||||
nvbe->is_bound = 0;
|
||||
}
|
||||
|
|
@ -242,6 +247,7 @@ nouveau_sgdma_init(struct drm_device *dev)
|
|||
pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
|
||||
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
if (dev_priv->card_type < NV_50) {
|
||||
/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
|
||||
* confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE
|
||||
|
|
@ -263,6 +269,7 @@ nouveau_sgdma_init(struct drm_device *dev)
|
|||
INSTANCE_WR(gpuobj, (i+4)/4, 0);
|
||||
}
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
dev_priv->gart_info.type = NOUVEAU_GART_SGDMA;
|
||||
dev_priv->gart_info.aper_base = 0;
|
||||
|
|
@ -343,11 +350,14 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
|
|||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
|
||||
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
|
||||
int pte;
|
||||
|
||||
pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
|
||||
if (dev_priv->card_type < NV_50) {
|
||||
instmem->prepare_access(dev, false);
|
||||
*page = INSTANCE_RD(gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
|
||||
instmem->finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,6 +202,8 @@ struct nouveau_instmem_engine {
|
|||
void (*clear)(struct drm_device *, struct nouveau_gpuobj *);
|
||||
int (*bind)(struct drm_device *, struct nouveau_gpuobj *);
|
||||
int (*unbind)(struct drm_device *, struct nouveau_gpuobj *);
|
||||
void (*prepare_access)(struct drm_device *, bool write);
|
||||
void (*finish_access)(struct drm_device *);
|
||||
};
|
||||
|
||||
struct nouveau_mc_engine {
|
||||
|
|
@ -273,7 +275,8 @@ struct drm_nouveau_private {
|
|||
|
||||
drm_local_map_t *mmio;
|
||||
drm_local_map_t *fb;
|
||||
drm_local_map_t *ramin; /* NV40 onwards */
|
||||
drm_local_map_t *ramin_map;
|
||||
drm_local_map_t *ramin;
|
||||
|
||||
int fifo_alloc_count;
|
||||
struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
|
||||
|
|
@ -633,6 +636,8 @@ extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
|
|||
extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern void nv04_instmem_prepare_access(struct drm_device *, bool write);
|
||||
extern void nv04_instmem_finish_access(struct drm_device *);
|
||||
|
||||
/* nv50_instmem.c */
|
||||
extern int nv50_instmem_init(struct drm_device *);
|
||||
|
|
@ -642,6 +647,8 @@ extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
|
|||
extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern void nv50_instmem_prepare_access(struct drm_device *, bool write);
|
||||
extern void nv50_instmem_finish_access(struct drm_device *);
|
||||
|
||||
/* nv04_mc.c */
|
||||
extern int nv04_mc_init(struct drm_device *);
|
||||
|
|
@ -720,8 +727,8 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
|
|||
#define nv_wait(reg,mask,val) nouveau_wait_until(dev, 1000000000ULL, (reg), \
|
||||
(mask), (val))
|
||||
/* PRAMIN access */
|
||||
#define nv_ri32(reg) nv_in32(dev_priv->ramin, (reg))
|
||||
#define nv_wi32(reg,val) nv_out32(dev_priv->ramin, (reg), (val))
|
||||
#define nv_ri32(reg) nv_in32(dev_priv->ramin_map, (reg))
|
||||
#define nv_wi32(reg,val) nv_out32(dev_priv->ramin_map, (reg), (val))
|
||||
/* object access */
|
||||
#define INSTANCE_RD(o,i) nv_ri32((o)->im_pramin->start + ((i)<<2))
|
||||
#define INSTANCE_WR(o,i,v) nv_wi32((o)->im_pramin->start + ((i)<<2), (v))
|
||||
|
|
|
|||
|
|
@ -438,10 +438,12 @@ nouveau_channel_idle(struct nouveau_channel *chan)
|
|||
return 1;
|
||||
}
|
||||
|
||||
engine->instmem.prepare_access(dev, false);
|
||||
if (INSTANCE_RD(ramfc, 0) != INSTANCE_RD(ramfc, 1))
|
||||
idle = 0;
|
||||
else
|
||||
idle = 1;
|
||||
engine->instmem.finish_access(dev);
|
||||
} else {
|
||||
idle = (nv_rd32(NV04_PFIFO_CACHE1_DMA_GET) ==
|
||||
nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT));
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ static int
|
|||
nouveau_graph_chid_from_grctx(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t inst;
|
||||
uint32_t inst, tmp;
|
||||
int i;
|
||||
|
||||
if (dev_priv->card_type < NV_40)
|
||||
|
|
@ -222,7 +222,11 @@ nouveau_graph_chid_from_grctx(struct drm_device *dev)
|
|||
if (inst == chan->ramin_grctx->instance)
|
||||
break;
|
||||
} else {
|
||||
if (inst == INSTANCE_RD(chan->ramin_grctx->gpuobj, 0))
|
||||
dev_priv->engine.instmem.prepare_access(dev, false);
|
||||
tmp = INSTANCE_RD(chan->ramin_grctx->gpuobj, 0);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
if (inst == tmp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
|
|||
|
||||
size &= ~(psz - 1);
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
if (flags & 0x80000000) {
|
||||
while (size) {
|
||||
struct nouveau_gpuobj *pt = pgt[virt / (512*1024*1024)];
|
||||
|
|
@ -329,6 +330,7 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
|
|||
virt += psz;
|
||||
}
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ static int
|
|||
nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv=dev->dev_private;
|
||||
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
|
||||
struct nouveau_channel *chan = dev_priv->fifos[ref->channel];
|
||||
struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
|
||||
struct nouveau_gpuobj *gpuobj = ref->gpuobj;
|
||||
|
|
@ -126,6 +127,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
|||
(gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
|
||||
}
|
||||
|
||||
instmem->prepare_access(dev, true);
|
||||
co = ho = nouveau_ramht_hash_handle(dev, ref->channel, ref->handle);
|
||||
do {
|
||||
if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
|
||||
|
|
@ -135,6 +137,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
|||
INSTANCE_WR(ramht, (co + 4)/4, ctx);
|
||||
|
||||
list_add_tail(&ref->list, &chan->ramht_refs);
|
||||
instmem->finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
DRM_DEBUG("collision ch%d 0x%08x: h=0x%08x\n",
|
||||
|
|
@ -149,6 +152,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
|||
break;
|
||||
}
|
||||
} while (co != ho);
|
||||
instmem->finish_access(dev);
|
||||
|
||||
DRM_ERROR("RAMHT space exhausted. ch=%d\n", ref->channel);
|
||||
return -ENOMEM;
|
||||
|
|
@ -158,6 +162,7 @@ static void
|
|||
nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
|
||||
struct nouveau_channel *chan = dev_priv->fifos[ref->channel];
|
||||
struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
|
||||
uint32_t co, ho;
|
||||
|
|
@ -167,6 +172,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
|||
return;
|
||||
}
|
||||
|
||||
instmem->prepare_access(dev, true);
|
||||
co = ho = nouveau_ramht_hash_handle(dev, ref->channel, ref->handle);
|
||||
do {
|
||||
if (nouveau_ramht_entry_valid(dev, ramht, co) &&
|
||||
|
|
@ -178,6 +184,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
|||
INSTANCE_WR(ramht, (co + 4)/4, 0x00000000);
|
||||
|
||||
list_del(&ref->list);
|
||||
instmem->finish_access(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -185,6 +192,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
|
|||
if (co >= dev_priv->ramht_size)
|
||||
co = 0;
|
||||
} while (co != ho);
|
||||
instmem->finish_access(dev);
|
||||
|
||||
DRM_ERROR("RAMHT entry not found. ch=%d, handle=0x%08x\n",
|
||||
ref->channel, ref->handle);
|
||||
|
|
@ -263,8 +271,10 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
|
|||
if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
|
||||
int i;
|
||||
|
||||
engine->instmem.prepare_access(dev, true);
|
||||
for (i = 0; i < gpuobj->im_pramin->size; i += 4)
|
||||
INSTANCE_WR(gpuobj, i/4, 0);
|
||||
engine->instmem.finish_access(dev);
|
||||
}
|
||||
|
||||
*gpuobj_ret = gpuobj;
|
||||
|
|
@ -582,8 +592,10 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
|
|||
}
|
||||
|
||||
if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
for (i = 0; i < gpuobj->im_pramin->size; i += 4)
|
||||
INSTANCE_WR(gpuobj, i/4, 0);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
}
|
||||
|
||||
if (pref) {
|
||||
|
|
@ -646,6 +658,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
|
|||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
|
||||
int ret;
|
||||
uint32_t is_scatter_gather = 0;
|
||||
|
||||
|
|
@ -682,6 +695,8 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
|
|||
return ret;
|
||||
}
|
||||
|
||||
instmem->prepare_access(dev, true);
|
||||
|
||||
if (dev_priv->card_type < NV_50) {
|
||||
uint32_t frame, adjust, pte_flags = 0;
|
||||
adjust = offset & 0x00000fff;
|
||||
|
|
@ -745,6 +760,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
|
|||
#else
|
||||
if (dma_mapping_error(dev->sg->busaddr[idx])) {
|
||||
#endif
|
||||
instmem->finish_access(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
|
@ -773,6 +789,8 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
|
|||
INSTANCE_WR(*gpuobj, 2, offset);
|
||||
INSTANCE_WR(*gpuobj, 5, flags5);
|
||||
}
|
||||
|
||||
instmem->finish_access(dev);
|
||||
|
||||
(*gpuobj)->engine = NVOBJ_ENGINE_SW;
|
||||
(*gpuobj)->class = class;
|
||||
|
|
@ -886,30 +904,32 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
|
|||
return ret;
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
if (dev_priv->card_type >= NV_50) {
|
||||
INSTANCE_WR(*gpuobj, 0, class);
|
||||
INSTANCE_WR(*gpuobj, 5, 0x00010000);
|
||||
} else {
|
||||
switch (class) {
|
||||
case NV_CLASS_NULL:
|
||||
INSTANCE_WR(*gpuobj, 0, 0x00001030);
|
||||
INSTANCE_WR(*gpuobj, 1, 0xFFFFFFFF);
|
||||
break;
|
||||
default:
|
||||
if (dev_priv->card_type >= NV_40) {
|
||||
INSTANCE_WR(*gpuobj, 0, class);
|
||||
switch (class) {
|
||||
case NV_CLASS_NULL:
|
||||
INSTANCE_WR(*gpuobj, 0, 0x00001030);
|
||||
INSTANCE_WR(*gpuobj, 1, 0xFFFFFFFF);
|
||||
break;
|
||||
default:
|
||||
if (dev_priv->card_type >= NV_40) {
|
||||
INSTANCE_WR(*gpuobj, 0, class);
|
||||
#ifdef __BIG_ENDIAN
|
||||
INSTANCE_WR(*gpuobj, 2, 0x01000000);
|
||||
INSTANCE_WR(*gpuobj, 2, 0x01000000);
|
||||
#endif
|
||||
} else {
|
||||
} else {
|
||||
#ifdef __BIG_ENDIAN
|
||||
INSTANCE_WR(*gpuobj, 0, class | 0x00080000);
|
||||
INSTANCE_WR(*gpuobj, 0, class | 0x00080000);
|
||||
#else
|
||||
INSTANCE_WR(*gpuobj, 0, class);
|
||||
INSTANCE_WR(*gpuobj, 0, class);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
(*gpuobj)->engine = NVOBJ_ENGINE_GR;
|
||||
(*gpuobj)->class = class;
|
||||
|
|
@ -972,6 +992,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
|
|||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
|
||||
struct nouveau_gpuobj *vram = NULL, *tt = NULL;
|
||||
int ret, i;
|
||||
|
||||
|
|
@ -998,6 +1019,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
|
|||
if (dev_priv->card_type >= NV_50) {
|
||||
uint32_t vm_offset, pde;
|
||||
|
||||
instmem->prepare_access(dev, true);
|
||||
|
||||
vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
|
||||
vm_offset += chan->ramin->gpuobj->im_pramin->start;
|
||||
if ((ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
|
||||
|
|
@ -1012,8 +1035,10 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
|
|||
ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
|
||||
dev_priv->gart_info.sg_ctxdma,
|
||||
&chan->vm_gart_pt);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
instmem->finish_access(dev);
|
||||
return ret;
|
||||
}
|
||||
INSTANCE_WR(chan->vm_pd, pde++,
|
||||
chan->vm_gart_pt->instance | 0x03);
|
||||
INSTANCE_WR(chan->vm_pd, pde++, 0x00000000);
|
||||
|
|
@ -1022,16 +1047,20 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
|
|||
drm_calloc(dev_priv->vm_vram_pt_nr,
|
||||
sizeof(struct nouveau_gpuobj_ref *),
|
||||
DRM_MEM_DRIVER);
|
||||
if (!chan->vm_vram_pt)
|
||||
if (!chan->vm_vram_pt) {
|
||||
instmem->finish_access(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2;
|
||||
for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
|
||||
ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
|
||||
dev_priv->vm_vram_pt[i],
|
||||
&chan->vm_vram_pt[i]);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
instmem->finish_access(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
INSTANCE_WR(chan->vm_pd, pde++,
|
||||
chan->vm_vram_pt[i]->instance | 0x61);
|
||||
|
|
@ -1039,6 +1068,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
|
|||
}
|
||||
}
|
||||
|
||||
instmem->finish_access(dev);
|
||||
|
||||
/* RAMHT */
|
||||
if (dev_priv->card_type < NV_50) {
|
||||
ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->instmem.clear = nv04_instmem_clear;
|
||||
engine->instmem.bind = nv04_instmem_bind;
|
||||
engine->instmem.unbind = nv04_instmem_unbind;
|
||||
engine->instmem.prepare_access = nv04_instmem_prepare_access;
|
||||
engine->instmem.finish_access = nv04_instmem_finish_access;
|
||||
engine->mc.init = nv04_mc_init;
|
||||
engine->mc.takedown = nv04_mc_takedown;
|
||||
engine->timer.init = nv04_timer_init;
|
||||
|
|
@ -76,6 +78,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->instmem.clear = nv04_instmem_clear;
|
||||
engine->instmem.bind = nv04_instmem_bind;
|
||||
engine->instmem.unbind = nv04_instmem_unbind;
|
||||
engine->instmem.prepare_access = nv04_instmem_prepare_access;
|
||||
engine->instmem.finish_access = nv04_instmem_finish_access;
|
||||
engine->mc.init = nv04_mc_init;
|
||||
engine->mc.takedown = nv04_mc_takedown;
|
||||
engine->timer.init = nv04_timer_init;
|
||||
|
|
@ -105,6 +109,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->instmem.clear = nv04_instmem_clear;
|
||||
engine->instmem.bind = nv04_instmem_bind;
|
||||
engine->instmem.unbind = nv04_instmem_unbind;
|
||||
engine->instmem.prepare_access = nv04_instmem_prepare_access;
|
||||
engine->instmem.finish_access = nv04_instmem_finish_access;
|
||||
engine->mc.init = nv04_mc_init;
|
||||
engine->mc.takedown = nv04_mc_takedown;
|
||||
engine->timer.init = nv04_timer_init;
|
||||
|
|
@ -134,6 +140,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->instmem.clear = nv04_instmem_clear;
|
||||
engine->instmem.bind = nv04_instmem_bind;
|
||||
engine->instmem.unbind = nv04_instmem_unbind;
|
||||
engine->instmem.prepare_access = nv04_instmem_prepare_access;
|
||||
engine->instmem.finish_access = nv04_instmem_finish_access;
|
||||
engine->mc.init = nv04_mc_init;
|
||||
engine->mc.takedown = nv04_mc_takedown;
|
||||
engine->timer.init = nv04_timer_init;
|
||||
|
|
@ -164,6 +172,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->instmem.clear = nv04_instmem_clear;
|
||||
engine->instmem.bind = nv04_instmem_bind;
|
||||
engine->instmem.unbind = nv04_instmem_unbind;
|
||||
engine->instmem.prepare_access = nv04_instmem_prepare_access;
|
||||
engine->instmem.finish_access = nv04_instmem_finish_access;
|
||||
engine->mc.init = nv40_mc_init;
|
||||
engine->mc.takedown = nv40_mc_takedown;
|
||||
engine->timer.init = nv04_timer_init;
|
||||
|
|
@ -196,6 +206,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
|||
engine->instmem.clear = nv50_instmem_clear;
|
||||
engine->instmem.bind = nv50_instmem_bind;
|
||||
engine->instmem.unbind = nv50_instmem_unbind;
|
||||
engine->instmem.prepare_access = nv50_instmem_prepare_access;
|
||||
engine->instmem.finish_access = nv50_instmem_finish_access;
|
||||
engine->mc.init = nv50_mc_init;
|
||||
engine->mc.takedown = nv50_mc_takedown;
|
||||
engine->timer.init = nv04_timer_init;
|
||||
|
|
@ -526,7 +538,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|||
}
|
||||
|
||||
/* map larger RAMIN aperture on NV40 cards */
|
||||
dev_priv->ramin = NULL;
|
||||
dev_priv->ramin_map = dev_priv->ramin = NULL;
|
||||
if (dev_priv->card_type >= NV_40) {
|
||||
int ramin_resource = 2;
|
||||
if (drm_get_resource_len(dev, ramin_resource) == 0)
|
||||
|
|
@ -812,8 +824,10 @@ static int nouveau_suspend(struct drm_device *dev)
|
|||
engine->graph.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]);
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
engine->instmem.prepare_access(dev, false);
|
||||
for (i = 0; i < susres->ramin_size / 4; i++)
|
||||
susres->ramin_copy[i] = nv_ri32(i << 2);
|
||||
engine->instmem.finish_access(dev);
|
||||
|
||||
/* reenable the fifo caches */
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_PUSH,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
|
|||
return ret;
|
||||
|
||||
/* Setup initial state */
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
RAMFC_WR(DMA_PUT, chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_GET, chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
|
||||
|
|
@ -69,6 +70,7 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
|
|||
NV_PFIFO_CACHE1_BIG_ENDIAN |
|
||||
#endif
|
||||
0));
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* enable the fifo dma operation */
|
||||
nv_wr32(NV04_PFIFO_MODE,nv_rd32(NV04_PFIFO_MODE) | (1<<chan->id));
|
||||
|
|
@ -93,6 +95,8 @@ nv04_fifo_load_context(struct nouveau_channel *chan)
|
|||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t tmp;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, false);
|
||||
|
||||
nv_wr32(NV03_PFIFO_CACHE1_PUSH1,
|
||||
NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
|
||||
|
||||
|
|
@ -108,6 +112,8 @@ nv04_fifo_load_context(struct nouveau_channel *chan)
|
|||
nv_wr32(NV04_PFIFO_CACHE1_ENGINE, RAMFC_RD(ENGINE));
|
||||
nv_wr32(NV04_PFIFO_CACHE1_PULL1, RAMFC_RD(PULL1_ENGINE));
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */
|
||||
tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31);
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_CTL, tmp);
|
||||
|
|
@ -122,6 +128,8 @@ nv04_fifo_save_context(struct nouveau_channel *chan)
|
|||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t tmp;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
|
||||
RAMFC_WR(DMA_PUT, nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT));
|
||||
RAMFC_WR(DMA_GET, nv_rd32(NV04_PFIFO_CACHE1_DMA_GET));
|
||||
|
||||
|
|
@ -134,5 +142,6 @@ nv04_fifo_save_context(struct nouveau_channel *chan)
|
|||
RAMFC_WR(ENGINE, nv_rd32(NV04_PFIFO_CACHE1_ENGINE));
|
||||
RAMFC_WR(PULL1_ENGINE, nv_rd32(NV04_PFIFO_CACHE1_PULL1));
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,3 +167,22 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
|
|||
gpuobj->im_bound = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nv04_instmem_prepare_access(struct drm_device *dev, bool write)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
BUG_ON(dev_priv->ramin_map != NULL);
|
||||
dev_priv->ramin_map = dev_priv->ramin;
|
||||
}
|
||||
|
||||
void
|
||||
nv04_instmem_finish_access(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
BUG_ON(dev_priv->ramin_map == NULL);
|
||||
dev_priv->ramin_map = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
|
|||
/* Fill entries that are seen filled in dumps of nvidia driver just
|
||||
* after channel's is put into DMA mode
|
||||
*/
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
RAMFC_WR(DMA_PUT , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_GET , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4);
|
||||
|
|
@ -72,6 +73,7 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
|
|||
NV_PFIFO_CACHE1_BIG_ENDIAN |
|
||||
#endif
|
||||
0);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* enable the fifo dma operation */
|
||||
nv_wr32(NV04_PFIFO_MODE,nv_rd32(NV04_PFIFO_MODE)|(1<<chan->id));
|
||||
|
|
@ -99,6 +101,8 @@ nv10_fifo_load_context(struct nouveau_channel *chan)
|
|||
nv_wr32(NV03_PFIFO_CACHE1_PUSH1,
|
||||
NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, false);
|
||||
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET));
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT));
|
||||
nv_wr32(NV10_PFIFO_CACHE1_REF_CNT , RAMFC_RD(REF_CNT));
|
||||
|
|
@ -125,6 +129,8 @@ nv10_fifo_load_context(struct nouveau_channel *chan)
|
|||
RAMFC_RD(DMA_SUBROUTINE));
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */
|
||||
tmp = nv_rd32(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31);
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_CTL, tmp);
|
||||
|
|
@ -139,6 +145,8 @@ nv10_fifo_save_context(struct nouveau_channel *chan)
|
|||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t tmp;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
|
||||
RAMFC_WR(DMA_PUT , nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT));
|
||||
RAMFC_WR(DMA_GET , nv_rd32(NV04_PFIFO_CACHE1_DMA_GET));
|
||||
RAMFC_WR(REF_CNT , nv_rd32(NV10_PFIFO_CACHE1_REF_CNT));
|
||||
|
|
@ -165,5 +173,6 @@ nv10_fifo_save_context(struct nouveau_channel *chan)
|
|||
nv_rd32(NV04_PFIFO_CACHE1_DMA_GET));
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,6 +606,7 @@ int nv20_graph_create_context(struct nouveau_channel *chan)
|
|||
return ret;
|
||||
|
||||
/* Initialise default context values */
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
ctx_init(dev, chan->ramin_grctx->gpuobj);
|
||||
|
||||
/* nv20: INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
|
||||
|
|
@ -615,6 +616,7 @@ int nv20_graph_create_context(struct nouveau_channel *chan)
|
|||
INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id,
|
||||
chan->ramin_grctx->instance >> 4);
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -626,7 +628,9 @@ void nv20_graph_destroy_context(struct nouveau_channel *chan)
|
|||
if (chan->ramin_grctx)
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, 0);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
}
|
||||
|
||||
int nv20_graph_load_context(struct nouveau_channel *chan)
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
|
|||
/* Fill entries that are seen filled in dumps of nvidia driver just
|
||||
* after channel's is put into DMA mode
|
||||
*/
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
RAMFC_WR(DMA_PUT , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_GET , chan->pushbuf_base);
|
||||
RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4);
|
||||
|
|
@ -66,6 +67,7 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
|
|||
RAMFC_WR(DMA_SUBROUTINE, 0);
|
||||
RAMFC_WR(GRCTX_INSTANCE, chan->ramin_grctx->instance >> 4);
|
||||
RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* enable the fifo dma operation */
|
||||
nv_wr32(NV04_PFIFO_MODE,nv_rd32(NV04_PFIFO_MODE)|(1<<chan->id));
|
||||
|
|
@ -91,6 +93,8 @@ nv40_fifo_load_context(struct nouveau_channel *chan)
|
|||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t tmp, tmp2;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, false);
|
||||
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET));
|
||||
nv_wr32(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT));
|
||||
nv_wr32(NV10_PFIFO_CACHE1_REF_CNT , RAMFC_RD(REF_CNT));
|
||||
|
|
@ -134,6 +138,8 @@ nv40_fifo_load_context(struct nouveau_channel *chan)
|
|||
tmp |= RAMFC_RD(DMA_TIMESLICE) & 0x1FFFF;
|
||||
nv_wr32(NV04_PFIFO_DMA_TIMESLICE, tmp);
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* Set channel active, and in DMA mode */
|
||||
nv_wr32(NV03_PFIFO_CACHE1_PUSH1,
|
||||
NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
|
||||
|
|
@ -152,6 +158,8 @@ nv40_fifo_save_context(struct nouveau_channel *chan)
|
|||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t tmp;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
|
||||
RAMFC_WR(DMA_PUT , nv_rd32(NV04_PFIFO_CACHE1_DMA_PUT));
|
||||
RAMFC_WR(DMA_GET , nv_rd32(NV04_PFIFO_CACHE1_DMA_GET));
|
||||
RAMFC_WR(REF_CNT , nv_rd32(NV10_PFIFO_CACHE1_REF_CNT));
|
||||
|
|
@ -192,6 +200,7 @@ nv40_fifo_save_context(struct nouveau_channel *chan)
|
|||
RAMFC_WR(UNK_48 , tmp);
|
||||
#endif
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1514,7 +1514,9 @@ nv40_graph_create_context(struct nouveau_channel *chan)
|
|||
return ret;
|
||||
|
||||
/* Initialise default context values */
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
ctx_init(dev, chan->ramin_grctx->gpuobj);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,14 @@ nv50_fifo_init_thingo(struct drm_device *dev)
|
|||
priv->cur_thingo = !priv->cur_thingo;
|
||||
|
||||
/* We never schedule channel 0 or 127 */
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
for (i = 1, nr = 0; i < 127; i++) {
|
||||
if (dev_priv->fifos[i]) {
|
||||
INSTANCE_WR(cur->gpuobj, nr++, i);
|
||||
}
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
nv_wr32(0x32f4, cur->instance >> 12);
|
||||
nv_wr32(0x32ec, nr);
|
||||
nv_wr32(0x2500, 0x101);
|
||||
|
|
@ -253,6 +256,8 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
|
|||
ramfc = chan->ramfc->gpuobj;
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
|
||||
INSTANCE_WR(ramfc, 0x08/4, chan->pushbuf_base);
|
||||
INSTANCE_WR(ramfc, 0x10/4, chan->pushbuf_base);
|
||||
INSTANCE_WR(ramfc, 0x48/4, chan->pushbuf->instance >> 4);
|
||||
|
|
@ -275,6 +280,8 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
|
|||
INSTANCE_WR(ramfc, 0x98/4, chan->ramin->instance >> 12);
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
ret = nv50_fifo_channel_enable(dev, chan->id, 0);
|
||||
if (ret) {
|
||||
DRM_ERROR("error enabling ch%d: %d\n", chan->id, ret);
|
||||
|
|
@ -315,6 +322,7 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
|
|||
DRM_DEBUG("ch%d\n", chan->id);
|
||||
|
||||
/*XXX: incomplete, only touches the regs that NV does */
|
||||
dev_priv->engine.instmem.prepare_access(dev, false);
|
||||
|
||||
nv_wr32(0x3244, INSTANCE_RD(ramfc, 0x08/4));
|
||||
nv_wr32(0x3240, INSTANCE_RD(ramfc, 0x10/4));
|
||||
|
|
@ -330,6 +338,8 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
|
|||
nv_wr32(0x3410, INSTANCE_RD(ramfc, 0x98/4));
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
nv_wr32(NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ nv50_graph_create_context(struct nouveau_channel *chan)
|
|||
ctx = chan->ramin_grctx->gpuobj;
|
||||
|
||||
hdr = IS_G80 ? 0x200 : 0x20;
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
INSTANCE_WR(ramin, (hdr + 0x00)/4, 0x00190002);
|
||||
INSTANCE_WR(ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
|
||||
grctx_size - 1);
|
||||
|
|
@ -189,6 +190,7 @@ nv50_graph_create_context(struct nouveau_channel *chan)
|
|||
INSTANCE_WR(ramin, (hdr + 0x0c)/4, 0);
|
||||
INSTANCE_WR(ramin, (hdr + 0x10)/4, 0);
|
||||
INSTANCE_WR(ramin, (hdr + 0x14)/4, 0x00010000);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x50:
|
||||
|
|
@ -222,6 +224,8 @@ nv50_graph_create_context(struct nouveau_channel *chan)
|
|||
break;
|
||||
}
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
|
||||
pos = 0;
|
||||
while (*ctxvals) {
|
||||
int cnt = *ctxvals++;
|
||||
|
|
@ -237,6 +241,8 @@ nv50_graph_create_context(struct nouveau_channel *chan)
|
|||
else
|
||||
INSTANCE_WR(ctx, 0x0011c/4, 0x00000002);
|
||||
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -252,8 +258,10 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
|
|||
int i, hdr;
|
||||
|
||||
hdr = IS_G80 ? 0x200 : 0x20;
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
for (i=hdr; i<hdr+24; i+=4)
|
||||
INSTANCE_WR(chan->ramin->gpuobj, i/4, 0);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,12 +176,14 @@ nv50_instmem_init(struct drm_device *dev)
|
|||
|
||||
/* Assume that praying isn't enough, check that we can re-read the
|
||||
* entire fake channel back from the PRAMIN BAR */
|
||||
dev_priv->engine.instmem.prepare_access(dev, false);
|
||||
for (i = 0; i < c_size; i+=4) {
|
||||
if (nv_rd32(NV_RAMIN + i) != nv_ri32(i)) {
|
||||
DRM_ERROR("Error reading back PRAMIN at 0x%08x\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
/* Global PRAMIN heap */
|
||||
if (nouveau_mem_init_heap(&dev_priv->ramin_heap,
|
||||
|
|
@ -289,6 +291,7 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
|
|||
DRM_DEBUG("first vram page: 0x%llx\n",
|
||||
gpuobj->im_backing->start);
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
while (pte < pte_end) {
|
||||
INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1);
|
||||
INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000);
|
||||
|
|
@ -296,6 +299,7 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
|
|||
pte += 8;
|
||||
vram += NV50_INSTMEM_PAGE_SIZE;
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
nv_wr32(0x070000, 0x00000001);
|
||||
while(nv_rd32(0x070000) & 1);
|
||||
|
|
@ -320,12 +324,34 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
|
|||
|
||||
pte = (gpuobj->im_pramin->start >> 12) << 3;
|
||||
pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte;
|
||||
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
while (pte < pte_end) {
|
||||
INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009);
|
||||
INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000);
|
||||
pte += 8;
|
||||
}
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
|
||||
gpuobj->im_bound = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nv50_instmem_prepare_access(struct drm_device *dev, bool write)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
BUG_ON(dev_priv->ramin_map != NULL);
|
||||
dev_priv->ramin_map = dev_priv->ramin;
|
||||
}
|
||||
|
||||
void
|
||||
nv50_instmem_finish_access(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
BUG_ON(dev_priv->ramin_map == NULL);
|
||||
dev_priv->ramin_map = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue