2 * Copyright 2012 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
22 #include <core/ramht.h>
23 #include <core/engine.h>
26 nvkm_ramht_hash(struct nvkm_ramht
*ramht
, int chid
, u32 handle
)
31 hash
^= (handle
& ((1 << ramht
->bits
) - 1));
32 handle
>>= ramht
->bits
;
35 hash
^= chid
<< (ramht
->bits
- 4);
40 nvkm_ramht_search(struct nvkm_ramht
*ramht
, int chid
, u32 handle
)
44 co
= ho
= nvkm_ramht_hash(ramht
, chid
, handle
);
46 if (ramht
->data
[co
].chid
== chid
) {
47 if (ramht
->data
[co
].handle
== handle
)
48 return ramht
->data
[co
].inst
;
51 if (++co
>= ramht
->size
)
59 nvkm_ramht_update(struct nvkm_ramht
*ramht
, int co
, struct nvkm_object
*object
,
60 int chid
, int addr
, u32 handle
, u32 context
)
62 struct nvkm_ramht_data
*data
= &ramht
->data
[co
];
63 u64 inst
= 0x00000040; /* just non-zero for <=g8x fifo ramht */
66 nvkm_gpuobj_del(&data
->inst
);
68 data
->handle
= handle
;
71 ret
= nvkm_object_bind(object
, ramht
->parent
, 16, &data
->inst
);
81 if (ramht
->device
->card_type
>= NV_50
)
82 inst
= data
->inst
->node
->offset
;
84 inst
= data
->inst
->addr
;
87 if (addr
< 0) context
|= inst
<< -addr
;
88 else context
|= inst
>> addr
;
91 nvkm_kmap(ramht
->gpuobj
);
92 nvkm_wo32(ramht
->gpuobj
, (co
<< 3) + 0, handle
);
93 nvkm_wo32(ramht
->gpuobj
, (co
<< 3) + 4, context
);
94 nvkm_done(ramht
->gpuobj
);
99 nvkm_ramht_remove(struct nvkm_ramht
*ramht
, int cookie
)
102 nvkm_ramht_update(ramht
, cookie
, NULL
, -1, 0, 0, 0);
106 nvkm_ramht_insert(struct nvkm_ramht
*ramht
, struct nvkm_object
*object
,
107 int chid
, int addr
, u32 handle
, u32 context
)
111 if (nvkm_ramht_search(ramht
, chid
, handle
))
114 co
= ho
= nvkm_ramht_hash(ramht
, chid
, handle
);
116 if (ramht
->data
[co
].chid
< 0) {
117 return nvkm_ramht_update(ramht
, co
, object
, chid
,
118 addr
, handle
, context
);
121 if (++co
>= ramht
->size
)
129 nvkm_ramht_del(struct nvkm_ramht
**pramht
)
131 struct nvkm_ramht
*ramht
= *pramht
;
133 nvkm_gpuobj_del(&ramht
->gpuobj
);
140 nvkm_ramht_new(struct nvkm_device
*device
, u32 size
, u32 align
,
141 struct nvkm_gpuobj
*parent
, struct nvkm_ramht
**pramht
)
143 struct nvkm_ramht
*ramht
;
146 if (!(ramht
= *pramht
= vzalloc(sizeof(*ramht
) +
147 (size
>> 3) * sizeof(*ramht
->data
))))
150 ramht
->device
= device
;
151 ramht
->parent
= parent
;
152 ramht
->size
= size
>> 3;
153 ramht
->bits
= order_base_2(ramht
->size
);
154 for (i
= 0; i
< ramht
->size
; i
++)
155 ramht
->data
[i
].chid
= -1;
157 ret
= nvkm_gpuobj_new(ramht
->device
, size
, align
, true,
158 ramht
->parent
, &ramht
->gpuobj
);
160 nvkm_ramht_del(pramht
);