OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [drm/] [via_mm.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3
 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the
13
 * next paragraph) shall be included in all copies or substantial portions
14
 * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
19
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
#define __NO_VERSION__
26
#include "via.h"
27
#include "drmP.h"
28
#include "via_drm.h"
29
#include "via_drv.h"
30
#include "via_ds.h"
31
#include "via_mm.h"
32
 
33
#define MAX_CONTEXT 100
34
 
35
unsigned int VIA_DEBUG = 1;
36
 
37
typedef struct {
38
        int used;
39
        int context;
40
        set_t *sets[2]; /* 0 for frame buffer, 1 for AGP , 2 for System*/
41
} via_context_t;
42
 
43
static via_context_t global_ppriv[MAX_CONTEXT];
44
 
45
static int add_alloc_set(int context, int type, unsigned int val)
46
{
47
        int i, retval = 0;
48
 
49
        for (i = 0; i < MAX_CONTEXT; i++)
50
        {
51
                if (global_ppriv[i].used && global_ppriv[i].context == context)
52
                {
53
                        retval = via_set_add(global_ppriv[i].sets[type], val);
54
                        break;
55
                }
56
        }
57
        return retval;
58
}
59
 
60
static int del_alloc_set(int context, int type, unsigned int val)
61
{
62
        int i, retval = 0;
63
 
64
        for (i = 0; i < MAX_CONTEXT; i++)
65
                if (global_ppriv[i].used && global_ppriv[i].context == context)
66
                {
67
                        retval = via_set_del(global_ppriv[i].sets[type], val);
68
                        break;
69
                }
70
        return retval;
71
}
72
 
73
/* agp memory management */
74
 
75
static memHeap_t *AgpHeap = NULL;
76
 
77
#warning "FIXME: heap re-init cases ?"
78
int via_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
79
                  unsigned long arg)
80
{
81
        drm_via_agp_t agp;
82
 
83
        if (copy_from_user(&agp, (drm_via_agp_t *)arg, sizeof(agp)))
84
                return -EFAULT;
85
 
86
        AgpHeap = via_mmInit(agp.offset, agp.size);
87
 
88
        DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
89
        return 0;
90
}
91
 
92
/* fb memory management */
93
static memHeap_t *FBHeap = NULL;
94
 
95
int via_fb_init(struct inode *inode, struct file *filp, unsigned int cmd,
96
                  unsigned long arg)
97
{
98
        drm_via_fb_t fb;
99
 
100
        if  (copy_from_user(&fb, (drm_via_fb_t *)arg, sizeof(fb)))
101
                return -EFAULT;
102
 
103
        FBHeap = via_mmInit(fb.offset, fb.size);
104
        DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
105
 
106
        return 0;
107
}
108
 
109
int via_init_context(int context)
110
{
111
        int i;
112
 
113
        for (i = 0; i < MAX_CONTEXT ; i++)
114
                if (global_ppriv[i].used && (global_ppriv[i].context == context))
115
                        break;
116
 
117
        if (i >= MAX_CONTEXT) {
118
                for (i = 0; i < MAX_CONTEXT ; i++) {
119
                        if (!global_ppriv[i].used) {
120
                                global_ppriv[i].context = context;
121
                                global_ppriv[i].used = 1;
122
                                global_ppriv[i].sets[0] = via_set_init();
123
                                global_ppriv[i].sets[1] = via_set_init();
124
                                DRM_DEBUG("init allocation set, socket=%d, context = %d\n",
125
                                         i, context);
126
                                break;
127
                        }
128
                }
129
 
130
                if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
131
                        (global_ppriv[i].sets[1] == NULL)) {
132
                        return 0;
133
                }
134
        }
135
 
136
        return 1;
137
}
138
 
139
int via_final_context(int context)
140
{
141
        int i;
142
        for (i=0; i<MAX_CONTEXT; i++)
143
                if (global_ppriv[i].used && (global_ppriv[i].context == context))
144
                        break;
145
 
146
        if (i < MAX_CONTEXT) {
147
                set_t *set;
148
                unsigned int item;
149
                int retval;
150
 
151
                DRM_DEBUG("find socket %d, context = %d\n", i, context);
152
 
153
                /* Video Memory */
154
                set = global_ppriv[i].sets[0];
155
                retval = via_set_first(set, &item);
156
                while (retval) {
157
                        DRM_DEBUG("free video memory 0x%x\n", item);
158
                        via_mmFreeMem((PMemBlock)item);
159
                        retval = via_set_next(set, &item);
160
                }
161
                via_set_destroy(set);
162
 
163
                /* AGP Memory */
164
                set = global_ppriv[i].sets[1];
165
                retval = via_set_first(set, &item);
166
                while (retval) {
167
                        DRM_DEBUG("free agp memory 0x%x\n", item);
168
                        via_mmFreeMem((PMemBlock)item);
169
                        retval = via_set_next(set, &item);
170
                }
171
                via_set_destroy(set);
172
 
173
                global_ppriv[i].used = 0;
174
        }
175
        return 1;
176
}
177
 
178
int via_mem_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
179
                  unsigned long arg)
180
{
181
        drm_via_mem_t mem;
182
 
183
        if (copy_from_user(&mem, (drm_via_mem_t *)arg, sizeof(mem)))
184
                return -EFAULT;
185
 
186
        switch (mem.type) {
187
                case VIDEO :
188
                        if (via_fb_alloc(&mem) < 0)
189
                                return -ENOMEM;
190
                        if (copy_to_user((drm_via_mem_t *)arg, &mem, sizeof(mem)))
191
                                return -EFAULT;
192
                        return 0;
193
                case AGP :
194
                        if (via_agp_alloc(&mem) < 0)
195
                                return -ENOMEM;
196
                        if (copy_to_user((drm_via_mem_t *)arg, &mem, sizeof(mem)))
197
                                return -EFAULT;
198
                        return 0;
199
        }
200
        return -EINVAL;
201
}
202
 
203
int via_fb_alloc(drm_via_mem_t* mem)
204
{
205
        drm_via_mm_t fb;
206
        PMemBlock block;
207
        int retval = 0;
208
 
209
        if (!FBHeap)
210
                return -1;
211
 
212
        fb.size = mem->size;
213
        fb.context = mem->context;
214
 
215
        block = via_mmAllocMem(FBHeap, fb.size, 5, 0);
216
        if (block) {
217
                fb.offset = block->ofs;
218
                fb.free = (unsigned int)block;
219
                if (!add_alloc_set(fb.context, VIDEO, fb.free)) {
220
                        DRM_DEBUG("adding to allocation set fails\n");
221
                        via_mmFreeMem((PMemBlock)fb.free);
222
                        retval = -1;
223
                }
224
        } else {
225
                fb.offset = 0;
226
                fb.size = 0;
227
                fb.free = 0;
228
        }
229
 
230
        mem->offset = fb.offset;
231
        mem->index = fb.free;
232
 
233
        DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, (int)fb.offset);
234
 
235
        return retval;
236
}
237
 
238
int via_agp_alloc(drm_via_mem_t* mem)
239
{
240
        drm_via_mm_t agp;
241
        PMemBlock block;
242
        int retval = 0;
243
 
244
        if (!AgpHeap)
245
                return -1;
246
 
247
        agp.size = mem->size;
248
        agp.context = mem->context;
249
 
250
        block = via_mmAllocMem(AgpHeap, agp.size, 5, 0);
251
        if (block) {
252
                agp.offset = block->ofs;
253
                agp.free = (unsigned int)block;
254
                if (!add_alloc_set(agp.context, AGP, agp.free)) {
255
                        DRM_DEBUG("adding to allocation set fails\n");
256
                        via_mmFreeMem((PMemBlock)agp.free);
257
                        retval = -1;
258
                }
259
        } else {
260
                agp.offset = 0;
261
                agp.size = 0;
262
                agp.free = 0;
263
        }
264
 
265
        mem->offset = agp.offset;
266
        mem->index = agp.free;
267
 
268
        DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, (unsigned int)agp.offset);
269
        return retval;
270
}
271
 
272
int via_mem_free(struct inode *inode, struct file *filp, unsigned int cmd,
273
                  unsigned long arg)
274
{
275
        drm_via_mem_t mem;
276
 
277
        if (copy_from_user(&mem, (drm_via_mem_t *)arg, sizeof(mem)))
278
                return -EFAULT;
279
 
280
        switch (mem.type)
281
        {
282
        case VIDEO :
283
            if (via_fb_free(&mem) == 0)
284
                return 0;
285
            break;
286
        case AGP :
287
            if (via_agp_free(&mem) == 0)
288
                return 0;
289
            break;
290
        }
291
        return -EINVAL;
292
}
293
 
294
int via_fb_free(drm_via_mem_t* mem)
295
{
296
        drm_via_mm_t fb;
297
        int retval = 0;
298
 
299
 
300
        if (!FBHeap)
301
                return -1;
302
 
303
        fb.free = mem->index;
304
        fb.context = mem->context;
305
 
306
        if (!fb.free)
307
                return -1;
308
 
309
        via_mmFreeMem((PMemBlock)fb.free);
310
 
311
        if (!del_alloc_set(fb.context, VIDEO, fb.free))
312
                retval = -1;
313
 
314
        DRM_DEBUG("free fb, free = %d\n", fb.free);
315
 
316
        return retval;
317
}
318
 
319
int via_agp_free(drm_via_mem_t* mem)
320
{
321
        drm_via_mm_t agp;
322
 
323
        int retval = 0;
324
 
325
        agp.free = mem->index;
326
        agp.context = mem->context;
327
 
328
        if (!agp.free)
329
                return -1;
330
 
331
        via_mmFreeMem((PMemBlock)agp.free);
332
 
333
        if (!del_alloc_set(agp.context, AGP, agp.free))
334
                retval = -1;
335
 
336
        DRM_DEBUG("free agp, free = %d\n", agp.free);
337
        return retval;
338
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.