1 /****************************************************************************
3 * Copyright (C) 2005 - 2011 by Vivante Corp.
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.
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.
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.
19 *****************************************************************************/
24 #include "gc_hal_kernel_linux.h"
26 #define _GC_OBJ_ZONE gcvZONE_KERNEL
28 /******************************************************************************\
29 ******************************* gckKERNEL API Code ******************************
30 \******************************************************************************/
32 /*******************************************************************************
34 ** gckKERNEL_QueryVideoMemory
36 ** Query the amount of video memory.
41 ** Pointer to an gckKERNEL object.
45 ** gcsHAL_INTERFACE * Interface
46 ** Pointer to an gcsHAL_INTERFACE structure that will be filled in with
47 ** the memory information.
50 gckKERNEL_QueryVideoMemory(
52 OUT gcsHAL_INTERFACE
* Interface
57 gcmkHEADER_ARG("Kernel=%p", Kernel
);
59 /* Verify the arguments. */
60 gcmkVERIFY_OBJECT(Kernel
, gcvOBJ_KERNEL
);
61 gcmkVERIFY_ARGUMENT(Interface
!= NULL
);
63 /* Extract the pointer to the gckGALDEVICE class. */
64 device
= (gckGALDEVICE
) Kernel
->context
;
66 /* Get internal memory size and physical address. */
67 Interface
->u
.QueryVideoMemory
.internalSize
= device
->internalSize
;
68 Interface
->u
.QueryVideoMemory
.internalPhysical
= device
->internalPhysical
;
70 /* Get external memory size and physical address. */
71 Interface
->u
.QueryVideoMemory
.externalSize
= device
->externalSize
;
72 Interface
->u
.QueryVideoMemory
.externalPhysical
= device
->externalPhysical
;
74 /* Get contiguous memory size and physical address. */
75 Interface
->u
.QueryVideoMemory
.contiguousSize
= device
->contiguousSize
;
76 Interface
->u
.QueryVideoMemory
.contiguousPhysical
= device
->contiguousPhysical
;
83 /*******************************************************************************
85 ** gckKERNEL_GetVideoMemoryPool
87 ** Get the gckVIDMEM object belonging to the specified pool.
92 ** Pointer to an gckKERNEL object.
95 ** Pool to query gckVIDMEM object for.
99 ** gckVIDMEM * VideoMemory
100 ** Pointer to a variable that will hold the pointer to the gckVIDMEM
101 ** object belonging to the requested pool.
104 gckKERNEL_GetVideoMemoryPool(
107 OUT gckVIDMEM
* VideoMemory
111 gckVIDMEM videoMemory
;
113 gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel
, Pool
);
115 /* Verify the arguments. */
116 gcmkVERIFY_OBJECT(Kernel
, gcvOBJ_KERNEL
);
117 gcmkVERIFY_ARGUMENT(VideoMemory
!= NULL
);
119 /* Extract the pointer to the gckGALDEVICE class. */
120 device
= (gckGALDEVICE
) Kernel
->context
;
122 /* Dispatch on pool. */
125 case gcvPOOL_LOCAL_INTERNAL
:
126 /* Internal memory. */
127 videoMemory
= device
->internalVidMem
;
130 case gcvPOOL_LOCAL_EXTERNAL
:
131 /* External memory. */
132 videoMemory
= device
->externalVidMem
;
137 videoMemory
= device
->contiguousVidMem
;
145 /* Return pointer to the gckVIDMEM object. */
146 *VideoMemory
= videoMemory
;
149 gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory
);
150 return (videoMemory
== NULL
) ? gcvSTATUS_OUT_OF_MEMORY
: gcvSTATUS_OK
;
153 /*******************************************************************************
155 ** gckKERNEL_MapMemory
157 ** Map video memory into the current process space.
162 ** Pointer to an gckKERNEL object.
164 ** gctPHYS_ADDR Physical
165 ** Physical address of video memory to map.
168 ** Number of bytes to map.
172 ** gctPOINTER * Logical
173 ** Pointer to a variable that will hold the base address of the mapped
179 IN gctPHYS_ADDR Physical
,
181 OUT gctPOINTER
* Logical
184 return gckOS_MapMemory(Kernel
->os
, Physical
, Bytes
, Logical
);
187 /*******************************************************************************
189 ** gckKERNEL_UnmapMemory
191 ** Unmap video memory from the current process space.
196 ** Pointer to an gckKERNEL object.
198 ** gctPHYS_ADDR Physical
199 ** Physical address of video memory to map.
202 ** Number of bytes to map.
204 ** gctPOINTER Logical
205 ** Base address of the mapped memory region.
212 gckKERNEL_UnmapMemory(
214 IN gctPHYS_ADDR Physical
,
216 IN gctPOINTER Logical
219 return gckOS_UnmapMemory(Kernel
->os
, Physical
, Bytes
, Logical
);
222 /*******************************************************************************
224 ** gckKERNEL_MapVideoMemory
226 ** Get the logical address for a hardware specific memory address for the
232 ** Pointer to an gckKERNEL object.
234 ** gctBOOL InUserSpace
235 ** gcvTRUE to map the memory into the user space.
238 ** Hardware specific memory address.
242 ** gctPOINTER * Logical
243 ** Pointer to a variable that will hold the logical address of the
244 ** specified memory address.
247 gckKERNEL_MapVideoMemoryEx(
250 IN gctBOOL InUserSpace
,
251 IN gctUINT32 Address
,
252 OUT gctPOINTER
* Logical
257 PLINUX_MDL_MAP mdlMap
;
259 gctUINT32 offset
, base
;
263 gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
264 Kernel
, InUserSpace
, Address
);
266 /* Verify the arguments. */
267 gcmkVERIFY_OBJECT(Kernel
, gcvOBJ_KERNEL
);
268 gcmkVERIFY_ARGUMENT(Logical
!= NULL
);
270 /* Extract the pointer to the gckGALDEVICE class. */
271 device
= (gckGALDEVICE
) Kernel
->context
;
274 if (Core
== gcvCORE_VG
)
276 /* Split the memory address into a pool type and offset. */
278 gckVGHARDWARE_SplitMemory(Kernel
->vg
->hardware
, Address
, &pool
, &offset
));
283 /* Split the memory address into a pool type and offset. */
285 gckHARDWARE_SplitMemory(Kernel
->hardware
, Address
, &pool
, &offset
));
288 /* Dispatch on pool. */
291 case gcvPOOL_LOCAL_INTERNAL
:
292 /* Internal memory. */
293 logical
= device
->internalLogical
;
296 case gcvPOOL_LOCAL_EXTERNAL
:
297 /* External memory. */
298 logical
= device
->externalLogical
;
303 if (device
->contiguousMapped
)
305 logical
= device
->contiguousBase
;
310 gckOS_GetProcessID(&processID
);
312 mdl
= (PLINUX_MDL
) device
->contiguousPhysical
;
314 mdlMap
= FindMdlMap(mdl
, processID
);
317 logical
= (gctPOINTER
) mdlMap
->vmaAddr
;
320 if (Core
== gcvCORE_VG
)
323 gckVGHARDWARE_SplitMemory(Kernel
->vg
->hardware
,
324 device
->contiguousVidMem
->baseAddress
,
332 gckHARDWARE_SplitMemory(Kernel
->hardware
,
333 device
->contiguousVidMem
->baseAddress
,
341 /* Invalid memory pool. */
342 gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT
);
345 /* Build logical address of specified address. */
346 *Logical
= (gctPOINTER
) ((gctUINT8_PTR
) logical
+ offset
);
349 gcmkFOOTER_ARG("*Logical=%p", *Logical
);
353 /* Retunn the status. */
358 /*******************************************************************************
360 ** gckKERNEL_MapVideoMemory
362 ** Get the logical address for a hardware specific memory address for the
368 ** Pointer to an gckKERNEL object.
370 ** gctBOOL InUserSpace
371 ** gcvTRUE to map the memory into the user space.
374 ** Hardware specific memory address.
378 ** gctPOINTER * Logical
379 ** Pointer to a variable that will hold the logical address of the
380 ** specified memory address.
383 gckKERNEL_MapVideoMemory(
385 IN gctBOOL InUserSpace
,
386 IN gctUINT32 Address
,
387 OUT gctPOINTER
* Logical
390 return gckKERNEL_MapVideoMemoryEx(Kernel
, gcvCORE_MAJOR
, InUserSpace
, Address
, Logical
);
392 /*******************************************************************************
396 ** This function iscalled by clients to notify the gckKERNRL object of an event.
401 ** Pointer to an gckKERNEL object.
403 ** gceNOTIFY Notification
404 ** Notification event.
413 IN gceNOTIFY Notification
,
419 gcmkHEADER_ARG("Kernel=%p Notification=%d Data=%d",
420 Kernel
, Notification
, Data
);
422 /* Verify the arguments. */
423 gcmkVERIFY_OBJECT(Kernel
, gcvOBJ_KERNEL
);
425 /* Dispatch on notifcation. */
426 switch (Notification
)
428 case gcvNOTIFY_INTERRUPT
:
429 /* Process the interrupt. */
430 #if COMMAND_PROCESSOR_VERSION > 1
431 status
= gckINTERRUPT_Notify(Kernel
->interrupt
, Data
);
433 status
= gckHARDWARE_Interrupt(Kernel
->hardware
, Data
);
438 status
= gcvSTATUS_OK
;
448 gckKERNEL_QuerySettings(
450 OUT gcsKERNEL_SETTINGS
* Settings
455 gcmkHEADER_ARG("Kernel=%p", Kernel
);
457 /* Verify the arguments. */
458 gcmkVERIFY_OBJECT(Kernel
, gcvOBJ_KERNEL
);
459 gcmkVERIFY_ARGUMENT(Settings
!= gcvNULL
);
461 /* Extract the pointer to the gckGALDEVICE class. */
462 device
= (gckGALDEVICE
) Kernel
->context
;
464 /* Fill in signal. */
465 Settings
->signal
= device
->signal
;
468 gcmkFOOTER_ARG("Settings->signal=%d", Settings
->signal
);