예제 #1
0
파일: nv84.c 프로젝트: AllenDou/linux
static void
nv84_crypt_intr(struct nouveau_subdev *subdev)
{
	struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
	struct nouveau_engine *engine = nv_engine(subdev);
	struct nouveau_object *engctx;
	struct nv84_crypt_priv *priv = (void *)subdev;
	u32 stat = nv_rd32(priv, 0x102130);
	u32 mthd = nv_rd32(priv, 0x102190);
	u32 data = nv_rd32(priv, 0x102194);
	u32 inst = nv_rd32(priv, 0x102188) & 0x7fffffff;
	int chid;

	engctx = nouveau_engctx_get(engine, inst);
	chid   = pfifo->chid(pfifo, engctx);

	if (stat) {
		nv_error(priv, "");
		nouveau_bitfield_print(nv84_crypt_intr_mask, stat);
		printk(" ch %d [0x%010llx] mthd 0x%04x data 0x%08x\n",
		       chid, (u64)inst << 12, mthd, data);
	}

	nv_wr32(priv, 0x102130, stat);
	nv_wr32(priv, 0x10200c, 0x10);

	nv50_fb_trap(nouveau_fb(priv), 1);
	nouveau_engctx_put(engctx);
}
예제 #2
0
static int
nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
		struct nouveau_oclass *oclass, void *data, u32 size,
		struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nv40_ram *ram;
	u32 pfb914 = nv_rd32(pfb, 0x100914);
	int ret;

	ret = nouveau_ram_create(parent, engine, oclass, &ram);
	*pobject = nv_object(ram);
	if (ret)
		return ret;

	switch (pfb914 & 0x00000003) {
	case 0x00000000: ram->base.type = NV_MEM_TYPE_DDR1; break;
	case 0x00000001: ram->base.type = NV_MEM_TYPE_DDR2; break;
	case 0x00000002: ram->base.type = NV_MEM_TYPE_GDDR3; break;
	case 0x00000003: break;
	}

	ram->base.size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
	ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
	ram->base.tags  =  nv_rd32(pfb, 0x100320);
	ram->base.calc = nv40_ram_calc;
	ram->base.prog = nv40_ram_prog;
	ram->base.tidy = nv40_ram_tidy;
	return 0;
}
예제 #3
0
static int
nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	      struct nouveau_oclass *oclass, void *data, u32 datasize,
	      struct nouveau_object **pobject)
{
	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nouveau_ram *ram;
	int ret;

	ret = nouveau_ram_create(parent, engine, oclass, &ram);
	*pobject = nv_object(ram);
	if (ret)
		return ret;

	ram->size = nv_rd32(pfb, 0x10020c);
	ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32);

	ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
			      (rsvd_head + rsvd_tail), 1);
	if (ret)
		return ret;

	ram->type   = NV_MEM_TYPE_STOLEN;
	ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
	ram->get = nv50_ram_get;
	ram->put = nv50_ram_put;
	return 0;
}
예제 #4
0
int
nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
                      struct drm_file *file_priv)
{
    struct nouveau_drm *drm = nouveau_drm(dev);
    struct nouveau_fb *pfb = nouveau_fb(drm->device);
    struct drm_nouveau_gem_new *req = data;
    struct nouveau_bo *nvbo = NULL;
    int ret = 0;

    drm->ttm.bdev.dev_mapping = drm->dev->dev_mapping;

    if (!pfb->memtype_valid(pfb, req->info.tile_flags)) {
        NV_ERROR(drm, "bad page flags: 0x%08x\n", req->info.tile_flags);
        return -EINVAL;
    }

    ret = nouveau_gem_new(dev, req->info.size, req->align,
                          req->info.domain, req->info.tile_mode,
                          req->info.tile_flags, &nvbo);
    if (ret)
        return ret;

    ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
    if (ret == 0) {
        ret = nouveau_gem_info(file_priv, nvbo->gem, &req->info);
        if (ret)
            drm_gem_handle_delete(file_priv, req->info.handle);
    }

    /* drop reference from allocate - handle holds it now */
    drm_gem_object_unreference_unlocked(nvbo->gem);
    return ret;
}
예제 #5
0
파일: ramnv41.c 프로젝트: 03199618/linux
static int
nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
		struct nouveau_oclass *oclass, void *data, u32 size,
		struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nouveau_ram *ram;
	u32 pfb474 = nv_rd32(pfb, 0x100474);
	int ret;

	ret = nouveau_ram_create(parent, engine, oclass, &ram);
	*pobject = nv_object(ram);
	if (ret)
		return ret;

	if (pfb474 & 0x00000004)
		ram->type = NV_MEM_TYPE_GDDR3;
	if (pfb474 & 0x00000002)
		ram->type = NV_MEM_TYPE_DDR2;
	if (pfb474 & 0x00000001)
		ram->type = NV_MEM_TYPE_DDR1;

	ram->size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
	ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
	ram->tags  =  nv_rd32(pfb, 0x100320);
	return 0;
}
예제 #6
0
static int
gm107_ltc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	       struct nouveau_oclass *oclass, void *data, u32 size,
	       struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nvkm_ltc_priv *priv;
	u32 parts, mask;
	int ret, i;

	ret = nvkm_ltc_create(parent, engine, oclass, &priv);
	*pobject = nv_object(priv);
	if (ret)
		return ret;

	parts = nv_rd32(priv, 0x022438);
	mask = nv_rd32(priv, 0x021c14);
	for (i = 0; i < parts; i++) {
		if (!(mask & (1 << i)))
			priv->ltc_nr++;
	}
	priv->lts_nr = nv_rd32(priv, 0x17e280) >> 28;

	ret = gf100_ltc_init_tag_ram(pfb, priv);
	if (ret)
		return ret;

	return 0;
}
예제 #7
0
static int
nv50_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
		  struct nouveau_oclass *oclass, void *data, u32 size,
		  struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nv50_instobj_priv *node;
	u32 align = (unsigned long)data;
	int ret;

	size  = max((size  + 4095) & ~4095, (u32)4096);
	align = max((align + 4095) & ~4095, (u32)4096);

	ret = nouveau_instobj_create(parent, engine, oclass, &node);
	*pobject = nv_object(node);
	if (ret)
		return ret;

	ret = pfb->ram.get(pfb, size, align, 0, 0x800, &node->mem);
	if (ret)
		return ret;

	node->base.addr = node->mem->offset;
	node->base.size = node->mem->size << 12;
	node->mem->page_shift = 12;
	return 0;
}
예제 #8
0
static int
gf100_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
	       struct nouveau_oclass *oclass, void *data, u32 size,
	       struct nouveau_object **pobject)
{
	struct gf100_ltcg_priv *priv;
	struct nouveau_fb *pfb = nouveau_fb(parent);
	u32 parts, mask;
	int ret, i;

	ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
	*pobject = nv_object(priv);
	if (ret)
		return ret;

	parts = nv_rd32(priv, 0x022438);
	mask = nv_rd32(priv, 0x022554);
	for (i = 0; i < parts; i++) {
		if (!(mask & (1 << i)))
			priv->ltc_nr++;
	}
	priv->lts_nr = nv_rd32(priv, 0x17e8dc) >> 28;

	ret = gf100_ltcg_init_tag_ram(pfb, priv);
	if (ret)
		return ret;

	priv->base.tags_alloc = gf100_ltcg_tags_alloc;
	priv->base.tags_free  = gf100_ltcg_tags_free;
	priv->base.tags_clear = gf100_ltcg_tags_clear;

	nv_subdev(priv)->intr = gf100_ltcg_intr;
	return 0;
}
예제 #9
0
static void
nv50_instobj_dtor(struct nouveau_object *object)
{
	struct nv50_instobj_priv *node = (void *)object;
	struct nouveau_fb *pfb = nouveau_fb(object);
	pfb->ram.put(pfb, &node->mem);
	nouveau_instobj_destroy(&node->base);
}
예제 #10
0
파일: gf100.c 프로젝트: andyqee/linux
void
gf100_ltc_dtor(struct nouveau_object *object)
{
	struct nouveau_fb *pfb = nouveau_fb(object);
	struct nvkm_ltc_priv *priv = (void *)object;

	nouveau_mm_fini(&priv->tags);
	nouveau_mm_free(&pfb->vram, &priv->tag_ram);

	nvkm_ltc_destroy(priv);
}
예제 #11
0
파일: nvc0.c 프로젝트: ChrisOHu/linux
static void
nvc0_ltcg_dtor(struct nouveau_object *object)
{
	struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
	struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
	struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);

	nouveau_mm_fini(&priv->tags);
	nouveau_mm_free(&pfb->vram, &priv->tag_ram);

	nouveau_ltcg_destroy(ltcg);
}
예제 #12
0
파일: ramnvc0.c 프로젝트: 24hours/linux
static void
nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic)
{
	struct nvc0_ram *ram = container_of(fuc, typeof(*ram), fuc);
	struct nouveau_fb *pfb = nouveau_fb(ram);
	u32 part = nv_rd32(pfb, 0x022438), i;
	u32 mask = nv_rd32(pfb, 0x022554);
	u32 addr = 0x110974;

	ram_wr32(fuc, 0x10f910, magic);
	ram_wr32(fuc, 0x10f914, magic);

	for (i = 0; (magic & 0x80000000) && i < part; addr += 0x1000, i++) {
		if (mask & (1 << i))
			continue;
		ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
	}
}
예제 #13
0
파일: ramnv4e.c 프로젝트: 03199618/linux
static int
nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
		struct nouveau_oclass *oclass, void *data, u32 size,
		struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nouveau_ram *ram;
	int ret;

	ret = nouveau_ram_create(parent, engine, oclass, &ram);
	*pobject = nv_object(ram);
	if (ret)
		return ret;

	ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
	ram->type = NV_MEM_TYPE_STOLEN;
	return 0;
}
예제 #14
0
파일: ramnv04.c 프로젝트: 383530895/linux
static int
nv04_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
		struct nouveau_oclass *oclass, void *data, u32 size,
		struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nouveau_ram *ram;
	u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
	int ret;

	ret = nouveau_ram_create(parent, engine, oclass, &ram);
	*pobject = nv_object(ram);
	if (ret)
		return ret;

	if (boot0 & 0x00000100) {
		ram->size  = ((boot0 >> 12) & 0xf) * 2 + 2;
		ram->size *= 1024 * 1024;
	} else {
예제 #15
0
파일: ramnve0.c 프로젝트: JorgeFRod/linux
static void
nve0_ram_nuts(struct nve0_ram *ram, struct ramfuc_reg *reg,
	      u32 _mask, u32 _data, u32 _copy)
{
	struct nve0_fb_priv *priv = (void *)nouveau_fb(ram);
	struct ramfuc *fuc = &ram->fuc.base;
	u32 addr = 0x110000 + (reg->addr[0] & 0xfff);
	u32 mask = _mask | _copy;
	u32 data = (_data & _mask) | (reg->data & _copy);
	u32 i;

	for (i = 0; i < 16; i++, addr += 0x1000) {
		if (ram->pnuts & (1 << i)) {
			u32 prev = nv_rd32(priv, addr);
			u32 next = (prev & ~mask) | data;
			nouveau_memx_wr32(fuc->memx, addr, next);
		}
	}
}
예제 #16
0
static int
nv10_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
		struct nouveau_oclass *oclass, void *data, u32 size,
		struct nouveau_object **pobject)
{
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nouveau_ram *ram;
	u32 cfg0 = nv_rd32(pfb, 0x100200);
	int ret;

	ret = nouveau_ram_create(parent, engine, oclass, &ram);
	*pobject = nv_object(ram);
	if (ret)
		return ret;

	if (cfg0 & 0x00000001)
		ram->type = NV_MEM_TYPE_DDR1;
	else
		ram->type = NV_MEM_TYPE_SDRAM;

	ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
	return 0;
}
예제 #17
0
int
nv30_graph_init(struct nouveau_object *object)
{
    struct nouveau_engine *engine = nv_engine(object);
    struct nv20_graph_priv *priv = (void *)engine;
    struct nouveau_fb *pfb = nouveau_fb(object);
    int ret, i;

    ret = nouveau_graph_init(&priv->base);
    if (ret)
        return ret;

    nv_wr32(priv, NV20_PGRAPH_CHANNEL_CTX_TABLE, priv->ctxtab->addr >> 4);

    nv_wr32(priv, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
    nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);

    nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
    nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000);
    nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x401287c0);
    nv_wr32(priv, 0x400890, 0x01b463ff);
    nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xf2de0475);
    nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00008000);
    nv_wr32(priv, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6);
    nv_wr32(priv, 0x400B80, 0x1003d888);
    nv_wr32(priv, 0x400B84, 0x0c000000);
    nv_wr32(priv, 0x400098, 0x00000000);
    nv_wr32(priv, 0x40009C, 0x0005ad00);
    nv_wr32(priv, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */
    nv_wr32(priv, 0x4000a0, 0x00000000);
    nv_wr32(priv, 0x4000a4, 0x00000008);
    nv_wr32(priv, 0x4008a8, 0xb784a400);
    nv_wr32(priv, 0x400ba0, 0x002f8685);
    nv_wr32(priv, 0x400ba4, 0x00231f3f);
    nv_wr32(priv, 0x4008a4, 0x40000020);

    if (nv_device(priv)->chipset == 0x34) {
        nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
        nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00200201);
        nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
        nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000008);
        nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
        nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000032);
        nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E00004);
        nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000002);
    }

    nv_wr32(priv, 0x4000c0, 0x00000016);

    /* Turn all the tiling regions off. */
    for (i = 0; i < pfb->tile.regions; i++)
        engine->tile_prog(engine, i);

    nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
    nv_wr32(priv, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
    nv_wr32(priv, 0x0040075c             , 0x00000001);

    /* begin RAM config */
    /* vramsz = pci_resource_len(priv->dev->pdev, 0) - 1; */
    nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200));
    nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204));
    if (nv_device(priv)->chipset != 0x34) {
        nv_wr32(priv, 0x400750, 0x00EA0000);
        nv_wr32(priv, 0x400754, nv_rd32(priv, 0x100200));
        nv_wr32(priv, 0x400750, 0x00EA0004);
        nv_wr32(priv, 0x400754, nv_rd32(priv, 0x100204));
    }
    return 0;
}
예제 #18
0
파일: base.c 프로젝트: 383530895/linux
int
nvkm_dmaobj_create_(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void **pdata, u32 *psize,
		    int length, void **pobject)
{
	union {
		struct nv_dma_v0 v0;
	} *args = *pdata;
	struct nouveau_instmem *instmem = nouveau_instmem(parent);
	struct nouveau_client *client = nouveau_client(parent);
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_fb *pfb = nouveau_fb(parent);
	struct nouveau_dmaobj *dmaobj;
	void *data = *pdata;
	u32 size = *psize;
	int ret;

	ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject);
	dmaobj = *pobject;
	if (ret)
		return ret;

	nv_ioctl(parent, "create dma size %d\n", *psize);
	if (nvif_unpack(args->v0, 0, 0, true)) {
		nv_ioctl(parent, "create dma vers %d target %d access %d "
				 "start %016llx limit %016llx\n",
			 args->v0.version, args->v0.target, args->v0.access,
			 args->v0.start, args->v0.limit);
		dmaobj->target = args->v0.target;
		dmaobj->access = args->v0.access;
		dmaobj->start  = args->v0.start;
		dmaobj->limit  = args->v0.limit;
	} else
		return ret;

	*pdata = data;
	*psize = size;

	if (dmaobj->start > dmaobj->limit)
		return -EINVAL;

	switch (dmaobj->target) {
	case NV_DMA_V0_TARGET_VM:
		dmaobj->target = NV_MEM_TARGET_VM;
		break;
	case NV_DMA_V0_TARGET_VRAM:
		if (!client->super) {
			if (dmaobj->limit >= pfb->ram->size - instmem->reserved)
				return -EACCES;
			if (device->card_type >= NV_50)
				return -EACCES;
		}
		dmaobj->target = NV_MEM_TARGET_VRAM;
		break;
	case NV_DMA_V0_TARGET_PCI:
		if (!client->super)
			return -EACCES;
		dmaobj->target = NV_MEM_TARGET_PCI;
		break;
	case NV_DMA_V0_TARGET_PCI_US:
	case NV_DMA_V0_TARGET_AGP:
		if (!client->super)
			return -EACCES;
		dmaobj->target = NV_MEM_TARGET_PCI_NOSNOOP;
		break;
	default:
		return -EINVAL;
	}

	switch (dmaobj->access) {
	case NV_DMA_V0_ACCESS_VM:
		dmaobj->access = NV_MEM_ACCESS_VM;
		break;
	case NV_DMA_V0_ACCESS_RD:
		dmaobj->access = NV_MEM_ACCESS_RO;
		break;
	case NV_DMA_V0_ACCESS_WR:
		dmaobj->access = NV_MEM_ACCESS_WO;
		break;
	case NV_DMA_V0_ACCESS_RDWR:
		dmaobj->access = NV_MEM_ACCESS_RW;
		break;
	default:
		return -EINVAL;
	}

	return ret;
}