Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nv50.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * 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 OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24 
25 #include <core/gpuobj.h>
26 #include <core/class.h>
27 
28 #include <subdev/fb.h>
29 #include <engine/dmaobj.h>
30 
33 };
34 
37 };
38 
39 static int
40 nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
41  struct nouveau_object *parent,
42  struct nouveau_dmaobj *dmaobj,
43  struct nouveau_gpuobj **pgpuobj)
44 {
45  u32 flags = nv_mclass(dmaobj);
46  int ret;
47 
48  switch (dmaobj->target) {
49  case NV_MEM_TARGET_VM:
50  flags |= 0x00000000;
51  flags |= 0x60000000; /* COMPRESSION_USEVM */
52  flags |= 0x1fc00000; /* STORAGE_TYPE_USEVM */
53  break;
54  case NV_MEM_TARGET_VRAM:
55  flags |= 0x00010000;
56  flags |= 0x00100000; /* ACCESSUS_USER_SYSTEM */
57  break;
58  case NV_MEM_TARGET_PCI:
59  flags |= 0x00020000;
60  flags |= 0x00100000; /* ACCESSUS_USER_SYSTEM */
61  break;
63  flags |= 0x00030000;
64  flags |= 0x00100000; /* ACCESSUS_USER_SYSTEM */
65  break;
66  default:
67  return -EINVAL;
68  }
69 
70  switch (dmaobj->access) {
71  case NV_MEM_ACCESS_VM:
72  break;
73  case NV_MEM_ACCESS_RO:
74  flags |= 0x00040000;
75  break;
76  case NV_MEM_ACCESS_WO:
77  case NV_MEM_ACCESS_RW:
78  flags |= 0x00080000;
79  break;
80  }
81 
82  ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
83  if (ret == 0) {
84  nv_wo32(*pgpuobj, 0x00, flags);
85  nv_wo32(*pgpuobj, 0x04, lower_32_bits(dmaobj->limit));
86  nv_wo32(*pgpuobj, 0x08, lower_32_bits(dmaobj->start));
87  nv_wo32(*pgpuobj, 0x0c, upper_32_bits(dmaobj->limit) << 24 |
88  upper_32_bits(dmaobj->start));
89  nv_wo32(*pgpuobj, 0x10, 0x00000000);
90  nv_wo32(*pgpuobj, 0x14, 0x00000000);
91  }
92 
93  return ret;
94 }
95 
96 static int
97 nv50_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
98  struct nouveau_oclass *oclass, void *data, u32 size,
99  struct nouveau_object **pobject)
100 {
101  struct nouveau_dmaeng *dmaeng = (void *)engine;
102  struct nv50_dmaobj_priv *dmaobj;
103  struct nouveau_gpuobj *gpuobj;
104  int ret;
105 
106  ret = nouveau_dmaobj_create(parent, engine, oclass,
107  data, size, &dmaobj);
108  *pobject = nv_object(dmaobj);
109  if (ret)
110  return ret;
111 
112  switch (nv_mclass(parent)) {
113  case NV_DEVICE_CLASS:
114  break;
119  ret = dmaeng->bind(dmaeng, *pobject, &dmaobj->base, &gpuobj);
120  nouveau_object_ref(NULL, pobject);
121  *pobject = nv_object(gpuobj);
122  break;
123  default:
124  return -EINVAL;
125  }
126 
127  return ret;
128 }
129 
130 static struct nouveau_ofuncs
131 nv50_dmaobj_ofuncs = {
132  .ctor = nv50_dmaobj_ctor,
133  .dtor = _nouveau_dmaobj_dtor,
134  .init = _nouveau_dmaobj_init,
135  .fini = _nouveau_dmaobj_fini,
136 };
137 
138 static struct nouveau_oclass
139 nv50_dmaobj_sclass[] = {
140  { 0x0002, &nv50_dmaobj_ofuncs },
141  { 0x0003, &nv50_dmaobj_ofuncs },
142  { 0x003d, &nv50_dmaobj_ofuncs },
143  {}
144 };
145 
146 static int
147 nv50_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
148  struct nouveau_oclass *oclass, void *data, u32 size,
149  struct nouveau_object **pobject)
150 {
151  struct nv50_dmaeng_priv *priv;
152  int ret;
153 
154  ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
155  *pobject = nv_object(priv);
156  if (ret)
157  return ret;
158 
159  priv->base.base.sclass = nv50_dmaobj_sclass;
160  priv->base.bind = nv50_dmaobj_bind;
161  return 0;
162 }
163 
164 struct nouveau_oclass
166  .handle = NV_ENGINE(DMAOBJ, 0x50),
167  .ofuncs = &(struct nouveau_ofuncs) {
168  .ctor = nv50_dmaeng_ctor,
169  .dtor = _nouveau_dmaeng_dtor,
170  .init = _nouveau_dmaeng_init,
171  .fini = _nouveau_dmaeng_fini,
172  },
173 };