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>
24 #include <core/object.h>
27 nvkm_ramht_hash(struct nvkm_ramht
*ramht
, int chid
, u32 handle
)
32 hash
^= (handle
& ((1 << ramht
->bits
) - 1));
33 handle
>>= ramht
->bits
;
36 hash
^= chid
<< (ramht
->bits
- 4);
41 nvkm_ramht_search(struct nvkm_ramht
*ramht
, int chid
, u32 handle
)
45 co
= ho
= nvkm_ramht_hash(ramht
, chid
, handle
);
47 if (ramht
->data
[co
].chid
== chid
) {
48 if (ramht
->data
[co
].handle
== handle
)
49 return ramht
->data
[co
].inst
;
52 if (++co
>= ramht
->size
)
60 nvkm_ramht_update(struct nvkm_ramht
*ramht
, int co
, struct nvkm_object
*object
,
61 int chid
, int addr
, u32 handle
, u32 context
)
63 struct nvkm_ramht_data
*data
= &ramht
->data
[co
];
64 u64 inst
= 0x00000040; /* just non-zero for <=g8x fifo ramht */
67 nvkm_gpuobj_del(&data
->inst
);
69 data
->handle
= handle
;
72 ret
= nvkm_object_bind(object
, ramht
->parent
, 16, &data
->inst
);
82 if (ramht
->device
->card_type
>= NV_50
)
83 inst
= data
->inst
->node
->offset
;
85 inst
= data
->inst
->addr
;
88 if (addr
< 0) context
|= inst
<< -addr
;
89 else context
|= inst
>> addr
;
92 nvkm_kmap(ramht
->gpuobj
);
93 nvkm_wo32(ramht
->gpuobj
, (co
<< 3) + 0, handle
);
94 nvkm_wo32(ramht
->gpuobj
, (co
<< 3) + 4, context
);
95 nvkm_done(ramht
->gpuobj
);
100 nvkm_ramht_remove(struct nvkm_ramht
*ramht
, int cookie
)
103 nvkm_ramht_update(ramht
, cookie
, NULL
, -1, 0, 0, 0);
107 nvkm_ramht_insert(struct nvkm_ramht
*ramht
, struct nvkm_object
*object
,
108 int chid
, int addr
, u32 handle
, u32 context
)
112 if (nvkm_ramht_search(ramht
, chid
, handle
))
115 co
= ho
= nvkm_ramht_hash(ramht
, chid
, handle
);
117 if (ramht
->data
[co
].chid
< 0) {
118 return nvkm_ramht_update(ramht
, co
, object
, chid
,
119 addr
, handle
, context
);
122 if (++co
>= ramht
->size
)
130 nvkm_ramht_del(struct nvkm_ramht
**pramht
)
132 struct nvkm_ramht
*ramht
= *pramht
;
134 nvkm_gpuobj_del(&ramht
->gpuobj
);
141 nvkm_ramht_new(struct nvkm_device
*device
, u32 size
, u32 align
,
142 struct nvkm_gpuobj
*parent
, struct nvkm_ramht
**pramht
)
144 struct nvkm_ramht
*ramht
;
147 if (!(ramht
= *pramht
= vzalloc(sizeof(*ramht
) +
148 (size
>> 3) * sizeof(*ramht
->data
))))
151 ramht
->device
= device
;
152 ramht
->parent
= parent
;
153 ramht
->size
= size
>> 3;
154 ramht
->bits
= order_base_2(ramht
->size
);
155 for (i
= 0; i
< ramht
->size
; i
++)
156 ramht
->data
[i
].chid
= -1;
158 ret
= nvkm_gpuobj_new(ramht
->device
, size
, align
, true,
159 ramht
->parent
, &ramht
->gpuobj
);
161 nvkm_ramht_del(pramht
);