]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
ENGR00240988: gpu: copy gpu-viv driver from 3.5.7 kernel
[karo-tx-linux.git] / drivers / mxc / gpu-viv / hal / os / linux / kernel / gc_hal_kernel_linux.c
1 /****************************************************************************
2 *
3 *    Copyright (C) 2005 - 2013 by Vivante Corp.
4 *
5 *    This program is free software; you can redistribute it and/or modify
6 *    it under the terms of the GNU General Public License as published by
7 *    the Free Software Foundation; either version 2 of the license, or
8 *    (at your option) any later version.
9 *
10 *    This program is distributed in the hope that it will be useful,
11 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 *    GNU General Public License for more details.
14 *
15 *    You should have received a copy of the GNU General Public License
16 *    along with this program; if not write to the Free Software
17 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *****************************************************************************/
20
21
22 #include "gc_hal_kernel_linux.h"
23
24 #define _GC_OBJ_ZONE    gcvZONE_KERNEL
25
26 /******************************************************************************\
27 ******************************* gckKERNEL API Code ******************************
28 \******************************************************************************/
29
30 /*******************************************************************************
31 **
32 **  gckKERNEL_QueryVideoMemory
33 **
34 **  Query the amount of video memory.
35 **
36 **  INPUT:
37 **
38 **      gckKERNEL Kernel
39 **          Pointer to an gckKERNEL object.
40 **
41 **  OUTPUT:
42 **
43 **      gcsHAL_INTERFACE * Interface
44 **          Pointer to an gcsHAL_INTERFACE structure that will be filled in with
45 **          the memory information.
46 */
47 gceSTATUS
48 gckKERNEL_QueryVideoMemory(
49     IN gckKERNEL Kernel,
50     OUT gcsHAL_INTERFACE * Interface
51     )
52 {
53     gckGALDEVICE device;
54
55     gcmkHEADER_ARG("Kernel=%p", Kernel);
56
57     /* Verify the arguments. */
58     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
59     gcmkVERIFY_ARGUMENT(Interface != NULL);
60
61     /* Extract the pointer to the gckGALDEVICE class. */
62     device = (gckGALDEVICE) Kernel->context;
63
64     /* Get internal memory size and physical address. */
65     Interface->u.QueryVideoMemory.internalSize = device->internalSize;
66     Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
67
68     /* Get external memory size and physical address. */
69     Interface->u.QueryVideoMemory.externalSize = device->externalSize;
70     Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
71
72     /* Get contiguous memory size and physical address. */
73     Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
74     Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
75
76     /* Success. */
77     gcmkFOOTER_NO();
78     return gcvSTATUS_OK;
79 }
80
81 /*******************************************************************************
82 **
83 **  gckKERNEL_GetVideoMemoryPool
84 **
85 **  Get the gckVIDMEM object belonging to the specified pool.
86 **
87 **  INPUT:
88 **
89 **      gckKERNEL Kernel
90 **          Pointer to an gckKERNEL object.
91 **
92 **      gcePOOL Pool
93 **          Pool to query gckVIDMEM object for.
94 **
95 **  OUTPUT:
96 **
97 **      gckVIDMEM * VideoMemory
98 **          Pointer to a variable that will hold the pointer to the gckVIDMEM
99 **          object belonging to the requested pool.
100 */
101 gceSTATUS
102 gckKERNEL_GetVideoMemoryPool(
103     IN gckKERNEL Kernel,
104     IN gcePOOL Pool,
105     OUT gckVIDMEM * VideoMemory
106     )
107 {
108     gckGALDEVICE device;
109     gckVIDMEM videoMemory;
110
111     gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel, Pool);
112
113     /* Verify the arguments. */
114     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
115     gcmkVERIFY_ARGUMENT(VideoMemory != NULL);
116
117     /* Extract the pointer to the gckGALDEVICE class. */
118     device = (gckGALDEVICE) Kernel->context;
119
120     /* Dispatch on pool. */
121     switch (Pool)
122     {
123     case gcvPOOL_LOCAL_INTERNAL:
124         /* Internal memory. */
125         videoMemory = device->internalVidMem;
126         break;
127
128     case gcvPOOL_LOCAL_EXTERNAL:
129         /* External memory. */
130         videoMemory = device->externalVidMem;
131         break;
132
133     case gcvPOOL_SYSTEM:
134         /* System memory. */
135         videoMemory = device->contiguousVidMem;
136         break;
137
138     default:
139         /* Unknown pool. */
140         videoMemory = NULL;
141     }
142
143     /* Return pointer to the gckVIDMEM object. */
144     *VideoMemory = videoMemory;
145
146     /* Return status. */
147     gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory);
148     return (videoMemory == NULL) ? gcvSTATUS_OUT_OF_MEMORY : gcvSTATUS_OK;
149 }
150
151 /*******************************************************************************
152 **
153 **  gckKERNEL_MapMemory
154 **
155 **  Map video memory into the current process space.
156 **
157 **  INPUT:
158 **
159 **      gckKERNEL Kernel
160 **          Pointer to an gckKERNEL object.
161 **
162 **      gctPHYS_ADDR Physical
163 **          Physical address of video memory to map.
164 **
165 **      gctSIZE_T Bytes
166 **          Number of bytes to map.
167 **
168 **  OUTPUT:
169 **
170 **      gctPOINTER * Logical
171 **          Pointer to a variable that will hold the base address of the mapped
172 **          memory region.
173 */
174 gceSTATUS
175 gckKERNEL_MapMemory(
176     IN gckKERNEL Kernel,
177     IN gctPHYS_ADDR Physical,
178     IN gctSIZE_T Bytes,
179     OUT gctPOINTER * Logical
180     )
181 {
182     gckKERNEL kernel = Kernel;
183     gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
184
185     return gckOS_MapMemory(Kernel->os, physical, Bytes, Logical);
186 }
187
188 /*******************************************************************************
189 **
190 **  gckKERNEL_UnmapMemory
191 **
192 **  Unmap video memory from the current process space.
193 **
194 **  INPUT:
195 **
196 **      gckKERNEL Kernel
197 **          Pointer to an gckKERNEL object.
198 **
199 **      gctPHYS_ADDR Physical
200 **          Physical address of video memory to map.
201 **
202 **      gctSIZE_T Bytes
203 **          Number of bytes to map.
204 **
205 **      gctPOINTER Logical
206 **          Base address of the mapped memory region.
207 **
208 **  OUTPUT:
209 **
210 **      Nothing.
211 */
212 gceSTATUS
213 gckKERNEL_UnmapMemory(
214     IN gckKERNEL Kernel,
215     IN gctPHYS_ADDR Physical,
216     IN gctSIZE_T Bytes,
217     IN gctPOINTER Logical
218     )
219 {
220     gckKERNEL kernel = Kernel;
221     gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
222
223     return gckOS_UnmapMemory(Kernel->os, physical, Bytes, Logical);
224 }
225
226 /*******************************************************************************
227 **
228 **  gckKERNEL_MapVideoMemory
229 **
230 **  Get the logical address for a hardware specific memory address for the
231 **  current process.
232 **
233 **  INPUT:
234 **
235 **      gckKERNEL Kernel
236 **          Pointer to an gckKERNEL object.
237 **
238 **      gctBOOL InUserSpace
239 **          gcvTRUE to map the memory into the user space.
240 **
241 **      gctUINT32 Address
242 **          Hardware specific memory address.
243 **
244 **  OUTPUT:
245 **
246 **      gctPOINTER * Logical
247 **          Pointer to a variable that will hold the logical address of the
248 **          specified memory address.
249 */
250 gceSTATUS
251 gckKERNEL_MapVideoMemoryEx(
252     IN gckKERNEL Kernel,
253     IN gceCORE Core,
254     IN gctBOOL InUserSpace,
255     IN gctUINT32 Address,
256     OUT gctPOINTER * Logical
257     )
258 {
259     gckGALDEVICE device;
260     PLINUX_MDL mdl;
261     PLINUX_MDL_MAP mdlMap;
262     gcePOOL pool;
263     gctUINT32 offset, base;
264     gceSTATUS status;
265     gctPOINTER logical;
266
267     gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
268                    Kernel, InUserSpace, Address);
269
270     /* Verify the arguments. */
271     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
272     gcmkVERIFY_ARGUMENT(Logical != NULL);
273
274     /* Extract the pointer to the gckGALDEVICE class. */
275     device = (gckGALDEVICE) Kernel->context;
276
277 #if gcdENABLE_VG
278     if (Core == gcvCORE_VG)
279     {
280         /* Split the memory address into a pool type and offset. */
281         gcmkONERROR(
282             gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
283     }
284     else
285 #endif
286     {
287         /* Split the memory address into a pool type and offset. */
288         gcmkONERROR(
289             gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset));
290     }
291
292     /* Dispatch on pool. */
293     switch (pool)
294     {
295     case gcvPOOL_LOCAL_INTERNAL:
296         /* Internal memory. */
297         logical = device->internalLogical;
298         break;
299
300     case gcvPOOL_LOCAL_EXTERNAL:
301         /* External memory. */
302         logical = device->externalLogical;
303         break;
304
305     case gcvPOOL_SYSTEM:
306         /* System memory. */
307         if (device->contiguousMapped)
308         {
309             logical = device->contiguousBase;
310         }
311         else
312         {
313             gctINT processID;
314             gckOS_GetProcessID(&processID);
315
316             mdl = (PLINUX_MDL) device->contiguousPhysical;
317
318             mdlMap = FindMdlMap(mdl, processID);
319             gcmkASSERT(mdlMap);
320
321             logical = (gctPOINTER) mdlMap->vmaAddr;
322         }
323 #if gcdENABLE_VG
324         if (Core == gcvCORE_VG)
325         {
326             gcmkVERIFY_OK(
327                 gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
328                                         device->contiguousVidMem->baseAddress,
329                                         &pool,
330                                         &base));
331         }
332         else
333 #endif
334         {
335             gcmkVERIFY_OK(
336                 gckHARDWARE_SplitMemory(Kernel->hardware,
337                                         device->contiguousVidMem->baseAddress,
338                                         &pool,
339                                         &base));
340         }
341         offset -= base;
342         break;
343
344     default:
345         /* Invalid memory pool. */
346         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
347     }
348
349     /* Build logical address of specified address. */
350     *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
351
352     /* Success. */
353     gcmkFOOTER_ARG("*Logical=%p", *Logical);
354     return gcvSTATUS_OK;
355
356 OnError:
357     /* Retunn the status. */
358     gcmkFOOTER();
359     return status;
360 }
361
362 /*******************************************************************************
363 **
364 **  gckKERNEL_MapVideoMemory
365 **
366 **  Get the logical address for a hardware specific memory address for the
367 **  current process.
368 **
369 **  INPUT:
370 **
371 **      gckKERNEL Kernel
372 **          Pointer to an gckKERNEL object.
373 **
374 **      gctBOOL InUserSpace
375 **          gcvTRUE to map the memory into the user space.
376 **
377 **      gctUINT32 Address
378 **          Hardware specific memory address.
379 **
380 **  OUTPUT:
381 **
382 **      gctPOINTER * Logical
383 **          Pointer to a variable that will hold the logical address of the
384 **          specified memory address.
385 */
386 gceSTATUS
387 gckKERNEL_MapVideoMemory(
388     IN gckKERNEL Kernel,
389     IN gctBOOL InUserSpace,
390     IN gctUINT32 Address,
391     OUT gctPOINTER * Logical
392     )
393 {
394     return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, Logical);
395 }
396 /*******************************************************************************
397 **
398 **  gckKERNEL_Notify
399 **
400 **  This function iscalled by clients to notify the gckKERNRL object of an event.
401 **
402 **  INPUT:
403 **
404 **      gckKERNEL Kernel
405 **          Pointer to an gckKERNEL object.
406 **
407 **      gceNOTIFY Notification
408 **          Notification event.
409 **
410 **  OUTPUT:
411 **
412 **      Nothing.
413 */
414 gceSTATUS
415 gckKERNEL_Notify(
416     IN gckKERNEL Kernel,
417     IN gceNOTIFY Notification,
418     IN gctBOOL Data
419     )
420 {
421     gceSTATUS status;
422
423     gcmkHEADER_ARG("Kernel=%p Notification=%d Data=%d",
424                    Kernel, Notification, Data);
425
426     /* Verify the arguments. */
427     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
428
429     /* Dispatch on notifcation. */
430     switch (Notification)
431     {
432     case gcvNOTIFY_INTERRUPT:
433         /* Process the interrupt. */
434 #if COMMAND_PROCESSOR_VERSION > 1
435         status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
436 #else
437         status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
438 #endif
439         break;
440
441     default:
442         status = gcvSTATUS_OK;
443         break;
444     }
445
446     /* Success. */
447     gcmkFOOTER();
448     return status;
449 }
450
451 gceSTATUS
452 gckKERNEL_QuerySettings(
453     IN gckKERNEL Kernel,
454     OUT gcsKERNEL_SETTINGS * Settings
455     )
456 {
457     gckGALDEVICE device;
458
459     gcmkHEADER_ARG("Kernel=%p", Kernel);
460
461     /* Verify the arguments. */
462     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
463     gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
464
465     /* Extract the pointer to the gckGALDEVICE class. */
466     device = (gckGALDEVICE) Kernel->context;
467
468     /* Fill in signal. */
469     Settings->signal = device->signal;
470
471     /* Success. */
472     gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);
473     return gcvSTATUS_OK;
474 }