1 /****************************************************************************
3 * Copyright (C) 2005 - 2013 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 *****************************************************************************/
22 #include "gc_hal_kernel_linux.h"
24 #define _GC_OBJ_ZONE gcvZONE_KERNEL
26 /******************************************************************************\
27 ******************************* gckKERNEL API Code ******************************
28 \******************************************************************************/
30 /*******************************************************************************
32 ** gckKERNEL_QueryVideoMemory
34 ** Query the amount of video memory.
39 ** Pointer to an gckKERNEL object.
43 ** gcsHAL_INTERFACE * Interface
44 ** Pointer to an gcsHAL_INTERFACE structure that will be filled in with
45 ** the memory information.
48 gckKERNEL_QueryVideoMemory(
50 OUT gcsHAL_INTERFACE * Interface
55 gcmkHEADER_ARG("Kernel=%p", Kernel);
57 /* Verify the arguments. */
58 gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
59 gcmkVERIFY_ARGUMENT(Interface != NULL);
61 /* Extract the pointer to the gckGALDEVICE class. */
62 device = (gckGALDEVICE) Kernel->context;
64 /* Get internal memory size and physical address. */
65 Interface->u.QueryVideoMemory.internalSize = device->internalSize;
66 Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
68 /* Get external memory size and physical address. */
69 Interface->u.QueryVideoMemory.externalSize = device->externalSize;
70 Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
72 /* Get contiguous memory size and physical address. */
73 Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
74 Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
81 /*******************************************************************************
83 ** gckKERNEL_GetVideoMemoryPool
85 ** Get the gckVIDMEM object belonging to the specified pool.
90 ** Pointer to an gckKERNEL object.
93 ** Pool to query gckVIDMEM object for.
97 ** gckVIDMEM * VideoMemory
98 ** Pointer to a variable that will hold the pointer to the gckVIDMEM
99 ** object belonging to the requested pool.
102 gckKERNEL_GetVideoMemoryPool(
105 OUT gckVIDMEM * VideoMemory
109 gckVIDMEM videoMemory;
111 gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel, Pool);
113 /* Verify the arguments. */
114 gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
115 gcmkVERIFY_ARGUMENT(VideoMemory != NULL);
117 /* Extract the pointer to the gckGALDEVICE class. */
118 device = (gckGALDEVICE) Kernel->context;
120 /* Dispatch on pool. */
123 case gcvPOOL_LOCAL_INTERNAL:
124 /* Internal memory. */
125 videoMemory = device->internalVidMem;
128 case gcvPOOL_LOCAL_EXTERNAL:
129 /* External memory. */
130 videoMemory = device->externalVidMem;
135 videoMemory = device->contiguousVidMem;
143 /* Return pointer to the gckVIDMEM object. */
144 *VideoMemory = videoMemory;
147 gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory);
148 return (videoMemory == NULL) ? gcvSTATUS_OUT_OF_MEMORY : gcvSTATUS_OK;
151 /*******************************************************************************
153 ** gckKERNEL_MapMemory
155 ** Map video memory into the current process space.
160 ** Pointer to an gckKERNEL object.
162 ** gctPHYS_ADDR Physical
163 ** Physical address of video memory to map.
166 ** Number of bytes to map.
170 ** gctPOINTER * Logical
171 ** Pointer to a variable that will hold the base address of the mapped
177 IN gctPHYS_ADDR Physical,
179 OUT gctPOINTER * Logical
182 gckKERNEL kernel = Kernel;
183 gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
185 return gckOS_MapMemory(Kernel->os, physical, Bytes, Logical);
188 /*******************************************************************************
190 ** gckKERNEL_UnmapMemory
192 ** Unmap video memory from the current process space.
197 ** Pointer to an gckKERNEL object.
199 ** gctPHYS_ADDR Physical
200 ** Physical address of video memory to map.
203 ** Number of bytes to map.
205 ** gctPOINTER Logical
206 ** Base address of the mapped memory region.
213 gckKERNEL_UnmapMemory(
215 IN gctPHYS_ADDR Physical,
217 IN gctPOINTER Logical
220 gckKERNEL kernel = Kernel;
221 gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
223 return gckOS_UnmapMemory(Kernel->os, physical, Bytes, Logical);
226 /*******************************************************************************
228 ** gckKERNEL_MapVideoMemory
230 ** Get the logical address for a hardware specific memory address for the
236 ** Pointer to an gckKERNEL object.
238 ** gctBOOL InUserSpace
239 ** gcvTRUE to map the memory into the user space.
242 ** Hardware specific memory address.
246 ** gctPOINTER * Logical
247 ** Pointer to a variable that will hold the logical address of the
248 ** specified memory address.
251 gckKERNEL_MapVideoMemoryEx(
254 IN gctBOOL InUserSpace,
255 IN gctUINT32 Address,
256 OUT gctPOINTER * Logical
261 PLINUX_MDL_MAP mdlMap;
263 gctUINT32 offset, base;
267 gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
268 Kernel, InUserSpace, Address);
270 /* Verify the arguments. */
271 gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
272 gcmkVERIFY_ARGUMENT(Logical != NULL);
274 /* Extract the pointer to the gckGALDEVICE class. */
275 device = (gckGALDEVICE) Kernel->context;
278 if (Core == gcvCORE_VG)
280 /* Split the memory address into a pool type and offset. */
282 gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
287 /* Split the memory address into a pool type and offset. */
289 gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset));
292 /* Dispatch on pool. */
295 case gcvPOOL_LOCAL_INTERNAL:
296 /* Internal memory. */
297 logical = device->internalLogical;
300 case gcvPOOL_LOCAL_EXTERNAL:
301 /* External memory. */
302 logical = device->externalLogical;
307 if (device->contiguousMapped)
309 logical = device->contiguousBase;
314 gckOS_GetProcessID(&processID);
316 mdl = (PLINUX_MDL) device->contiguousPhysical;
318 mdlMap = FindMdlMap(mdl, processID);
321 logical = (gctPOINTER) mdlMap->vmaAddr;
324 if (Core == gcvCORE_VG)
327 gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
328 device->contiguousVidMem->baseAddress,
335 gctUINT32 baseAddress = 0;
337 if (Kernel->hardware->mmuVersion == 0)
339 gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
343 gckHARDWARE_SplitMemory(Kernel->hardware,
344 device->contiguousVidMem->baseAddress - baseAddress,
352 /* Invalid memory pool. */
353 gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
356 /* Build logical address of specified address. */
357 *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
360 gcmkFOOTER_ARG("*Logical=%p", *Logical);
364 /* Retunn the status. */
369 /*******************************************************************************
371 ** gckKERNEL_MapVideoMemory
373 ** Get the logical address for a hardware specific memory address for the
379 ** Pointer to an gckKERNEL object.
381 ** gctBOOL InUserSpace
382 ** gcvTRUE to map the memory into the user space.
385 ** Hardware specific memory address.
389 ** gctPOINTER * Logical
390 ** Pointer to a variable that will hold the logical address of the
391 ** specified memory address.
394 gckKERNEL_MapVideoMemory(
396 IN gctBOOL InUserSpace,
397 IN gctUINT32 Address,
398 OUT gctPOINTER * Logical
401 return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, Logical);
403 /*******************************************************************************
407 ** This function iscalled by clients to notify the gckKERNRL object of an event.
412 ** Pointer to an gckKERNEL object.
414 ** gceNOTIFY Notification
415 ** Notification event.
424 IN gceNOTIFY Notification,
430 gcmkHEADER_ARG("Kernel=%p Notification=%d Data=%d",
431 Kernel, Notification, Data);
433 /* Verify the arguments. */
434 gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
436 /* Dispatch on notifcation. */
437 switch (Notification)
439 case gcvNOTIFY_INTERRUPT:
440 /* Process the interrupt. */
441 #if COMMAND_PROCESSOR_VERSION > 1
442 status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
444 status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
449 status = gcvSTATUS_OK;
459 gckKERNEL_QuerySettings(
461 OUT gcsKERNEL_SETTINGS * Settings
466 gcmkHEADER_ARG("Kernel=%p", Kernel);
468 /* Verify the arguments. */
469 gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
470 gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
472 /* Extract the pointer to the gckGALDEVICE class. */
473 device = (gckGALDEVICE) Kernel->context;
475 /* Fill in signal. */
476 Settings->signal = device->signal;
479 gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);