1/* $NetBSD: nouveau_engine_dmaobj_base.c,v 1.1.1.1 2014/08/06 12:36:24 riastradh Exp $ */
2
3/*
4 * Copyright 2012 Red Hat Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Ben Skeggs
25 */
26
27#include <sys/cdefs.h>
28__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_dmaobj_base.c,v 1.1.1.1 2014/08/06 12:36:24 riastradh Exp $");
29
30#include <core/object.h>
31#include <core/class.h>
32
33#include <subdev/fb.h>
34#include <engine/dmaobj.h>
35
36static int
37nouveau_dmaobj_ctor(struct nouveau_object *parent,
38 struct nouveau_object *engine,
39 struct nouveau_oclass *oclass, void *data, u32 size,
40 struct nouveau_object **pobject)
41{
42 struct nouveau_dmaeng *dmaeng = (void *)engine;
43 struct nouveau_dmaobj *dmaobj;
44 struct nouveau_gpuobj *gpuobj;
45 struct nv_dma_class *args = data;
46 int ret;
47
48 if (size < sizeof(*args))
49 return -EINVAL;
50
51 ret = nouveau_object_create(parent, engine, oclass, 0, &dmaobj);
52 *pobject = nv_object(dmaobj);
53 if (ret)
54 return ret;
55
56 switch (args->flags & NV_DMA_TARGET_MASK) {
57 case NV_DMA_TARGET_VM:
58 dmaobj->target = NV_MEM_TARGET_VM;
59 break;
60 case NV_DMA_TARGET_VRAM:
61 dmaobj->target = NV_MEM_TARGET_VRAM;
62 break;
63 case NV_DMA_TARGET_PCI:
64 dmaobj->target = NV_MEM_TARGET_PCI;
65 break;
66 case NV_DMA_TARGET_PCI_US:
67 case NV_DMA_TARGET_AGP:
68 dmaobj->target = NV_MEM_TARGET_PCI_NOSNOOP;
69 break;
70 default:
71 return -EINVAL;
72 }
73
74 switch (args->flags & NV_DMA_ACCESS_MASK) {
75 case NV_DMA_ACCESS_VM:
76 dmaobj->access = NV_MEM_ACCESS_VM;
77 break;
78 case NV_DMA_ACCESS_RD:
79 dmaobj->access = NV_MEM_ACCESS_RO;
80 break;
81 case NV_DMA_ACCESS_WR:
82 dmaobj->access = NV_MEM_ACCESS_WO;
83 break;
84 case NV_DMA_ACCESS_RDWR:
85 dmaobj->access = NV_MEM_ACCESS_RW;
86 break;
87 default:
88 return -EINVAL;
89 }
90
91 dmaobj->start = args->start;
92 dmaobj->limit = args->limit;
93 dmaobj->conf0 = args->conf0;
94
95 switch (nv_mclass(parent)) {
96 case NV_DEVICE_CLASS:
97 /* delayed, or no, binding */
98 break;
99 default:
100 ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj);
101 if (ret == 0) {
102 nouveau_object_ref(NULL, pobject);
103 *pobject = nv_object(gpuobj);
104 }
105 break;
106 }
107
108 return ret;
109}
110
111static struct nouveau_ofuncs
112nouveau_dmaobj_ofuncs = {
113 .ctor = nouveau_dmaobj_ctor,
114 .dtor = nouveau_object_destroy,
115 .init = nouveau_object_init,
116 .fini = nouveau_object_fini,
117};
118
119struct nouveau_oclass
120nouveau_dmaobj_sclass[] = {
121 { NV_DMA_FROM_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
122 { NV_DMA_TO_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
123 { NV_DMA_IN_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
124 {}
125};
126