139 lines · c
1/*2 * Copyright 2012 Red Hat Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: Ben Skeggs23 */24#include "user.h"25 26#include <core/client.h>27#include <core/gpuobj.h>28#include <subdev/fb.h>29 30#include <nvif/cl0002.h>31#include <nvif/unpack.h>32 33static const struct nvkm_object_func nvkm_dmaobj_func;34struct nvkm_dmaobj *35nvkm_dmaobj_search(struct nvkm_client *client, u64 handle)36{37 struct nvkm_object *object;38 39 object = nvkm_object_search(client, handle, &nvkm_dmaobj_func);40 if (IS_ERR(object))41 return (void *)object;42 43 return nvkm_dmaobj(object);44}45 46static int47nvkm_dmaobj_bind(struct nvkm_object *base, struct nvkm_gpuobj *gpuobj,48 int align, struct nvkm_gpuobj **pgpuobj)49{50 struct nvkm_dmaobj *dmaobj = nvkm_dmaobj(base);51 return dmaobj->func->bind(dmaobj, gpuobj, align, pgpuobj);52}53 54static void *55nvkm_dmaobj_dtor(struct nvkm_object *base)56{57 return nvkm_dmaobj(base);58}59 60static const struct nvkm_object_func61nvkm_dmaobj_func = {62 .dtor = nvkm_dmaobj_dtor,63 .bind = nvkm_dmaobj_bind,64};65 66int67nvkm_dmaobj_ctor(const struct nvkm_dmaobj_func *func, struct nvkm_dma *dma,68 const struct nvkm_oclass *oclass, void **pdata, u32 *psize,69 struct nvkm_dmaobj *dmaobj)70{71 union {72 struct nv_dma_v0 v0;73 } *args = *pdata;74 struct nvkm_object *parent = oclass->parent;75 void *data = *pdata;76 u32 size = *psize;77 int ret = -ENOSYS;78 79 nvkm_object_ctor(&nvkm_dmaobj_func, oclass, &dmaobj->object);80 dmaobj->func = func;81 dmaobj->dma = dma;82 83 nvif_ioctl(parent, "create dma size %d\n", *psize);84 if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {85 nvif_ioctl(parent, "create dma vers %d target %d access %d "86 "start %016llx limit %016llx\n",87 args->v0.version, args->v0.target, args->v0.access,88 args->v0.start, args->v0.limit);89 dmaobj->target = args->v0.target;90 dmaobj->access = args->v0.access;91 dmaobj->start = args->v0.start;92 dmaobj->limit = args->v0.limit;93 } else94 return ret;95 96 *pdata = data;97 *psize = size;98 99 if (dmaobj->start > dmaobj->limit)100 return -EINVAL;101 102 switch (dmaobj->target) {103 case NV_DMA_V0_TARGET_VM:104 dmaobj->target = NV_MEM_TARGET_VM;105 break;106 case NV_DMA_V0_TARGET_VRAM:107 dmaobj->target = NV_MEM_TARGET_VRAM;108 break;109 case NV_DMA_V0_TARGET_PCI:110 dmaobj->target = NV_MEM_TARGET_PCI;111 break;112 case NV_DMA_V0_TARGET_PCI_US:113 case NV_DMA_V0_TARGET_AGP:114 dmaobj->target = NV_MEM_TARGET_PCI_NOSNOOP;115 break;116 default:117 return -EINVAL;118 }119 120 switch (dmaobj->access) {121 case NV_DMA_V0_ACCESS_VM:122 dmaobj->access = NV_MEM_ACCESS_VM;123 break;124 case NV_DMA_V0_ACCESS_RD:125 dmaobj->access = NV_MEM_ACCESS_RO;126 break;127 case NV_DMA_V0_ACCESS_WR:128 dmaobj->access = NV_MEM_ACCESS_WO;129 break;130 case NV_DMA_V0_ACCESS_RDWR:131 dmaobj->access = NV_MEM_ACCESS_RW;132 break;133 default:134 return -EINVAL;135 }136 137 return ret;138}139