diff options
Diffstat (limited to 'drivers/mxc/gpu-viv/arch/GC350/hal/kernel')
4 files changed, 2520 insertions, 0 deletions
diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c new file mode 100644 index 000000000000..96ea0f14eead --- /dev/null +++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c @@ -0,0 +1,929 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2011 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + + + +#include "gc_hal.h" +#include "gc_hal_kernel.h" + +#if gcdENABLE_VG + +#include "gc_hal_kernel_hardware_command_vg.h" + +#define _GC_OBJ_ZONE gcvZONE_COMMAND + +/******************************************************************************\ +****************************** gckVGCOMMAND API code ***************************** +\******************************************************************************/ + +/******************************************************************************* +** +** gckVGCOMMAND_InitializeInfo +** +** Initialize architecture dependent command buffer information. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to the Command object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckVGCOMMAND_InitializeInfo( + IN gckVGCOMMAND Command + ) +{ + gceSTATUS status; + gcmkHEADER_ARG("Command=0x%x", Command); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + do + { + /* Reset interrupts. */ + Command->info.feBufferInt = -1; + Command->info.tsOverflowInt = -1; + + /* Set command buffer attributes. */ + Command->info.addressAlignment = 64; + Command->info.commandAlignment = 8; + + /* Determine command alignment address mask. */ + Command->info.addressMask = ((((gctUINT32) (Command->info.addressAlignment - 1)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) ((gctUINT32) (0 ) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))); + + /* Query the number of bytes needed by the STATE command. */ + gcmkERR_BREAK(gckVGCOMMAND_StateCommand( + Command, 0x0, gcvNULL, (gctUINT32)~0, 0, + &Command->info.stateCommandSize + )); + + /* Query the number of bytes needed by the RESTART command. */ + gcmkERR_BREAK(gckVGCOMMAND_RestartCommand( + Command, gcvNULL, (gctUINT32)~0, 0, + &Command->info.restartCommandSize + )); + + /* Query the number of bytes needed by the FETCH command. */ + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand( + Command, gcvNULL, (gctUINT32)~0, 0, + &Command->info.fetchCommandSize + )); + + /* Query the number of bytes needed by the CALL command. */ + gcmkERR_BREAK(gckVGCOMMAND_CallCommand( + Command, gcvNULL, (gctUINT32)~0, 0, + &Command->info.callCommandSize + )); + + /* Query the number of bytes needed by the RETURN command. */ + gcmkERR_BREAK(gckVGCOMMAND_ReturnCommand( + Command, gcvNULL, + &Command->info.returnCommandSize + )); + + /* Query the number of bytes needed by the EVENT command. */ + gcmkERR_BREAK(gckVGCOMMAND_EventCommand( + Command, gcvNULL, gcvBLOCK_PIXEL, -1, + &Command->info.eventCommandSize + )); + + /* Query the number of bytes needed by the END command. */ + gcmkERR_BREAK(gckVGCOMMAND_EndCommand( + Command, gcvNULL, -1, + &Command->info.endCommandSize + )); + + /* Determine the tail reserve size. */ + Command->info.staticTailSize = gcmMAX( + Command->info.fetchCommandSize, + gcmMAX( + Command->info.returnCommandSize, + Command->info.endCommandSize + ) + ); + + /* Determine the maximum tail size. */ + Command->info.dynamicTailSize + = Command->info.staticTailSize + + Command->info.eventCommandSize * gcvBLOCK_COUNT; + } + while (gcvFALSE); + + gcmkFOOTER(); + /* Return status. */ + return status; +} + +/******************************************************************************* +** +** gckVGCOMMAND_StateCommand +** +** Append a STATE command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to an gckVGCOMMAND object. +** +** gctUINT32 Pipe +** Harwdare destination pipe. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** STATE command at or gcvNULL to query the size of the command. +** +** gctUINT32 Address +** Starting register address of the state buffer. +** If 'Logical' is gcvNULL, this argument is ignored. +** +** gctUINT32 Count +** Number of states in state buffer. +** If 'Logical' is gcvNULL, this argument is ignored. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the STATE command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the STATE command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_StateCommand( + IN gckVGCOMMAND Command, + IN gctUINT32 Pipe, + IN gctPOINTER Logical, + IN gctUINT32 Address, + IN gctSIZE_T Count, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x", + Command, Pipe, Logical, Address, Count, Bytes); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append STATE. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12))) | (((gctUINT32) ((gctUINT32) (Pipe) & ((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12))); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the STATE command. */ + *Bytes = 4 * (Count + 1); + } + } + else + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append LOAD_STATE. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the STATE command. */ + *Bytes = 4 * (Count + 1); + } + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGCOMMAND_RestartCommand +** +** Form a RESTART command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to an gckVGCOMMAND object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** RESTART command at or gcvNULL to query the size of the command. +** +** gctUINT32 FetchAddress +** The address of another command buffer to be executed by this RESTART +** command. If 'Logical' is gcvNULL, this argument is ignored. +** +** gctUINT FetchCount +** The number of 64-bit data quantities in another command buffer to +** be executed by this RESTART command. If 'Logical' is gcvNULL, this +** argument is ignored. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the RESTART command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the RESTART command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_RestartCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctUINT32 FetchAddress, + IN gctUINT FetchCount, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x", + Command, Logical, FetchAddress, FetchCount, Bytes); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + gctUINT32 beginEndMark; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Determine Begin/End flag. */ + beginEndMark = (FetchCount > 0) + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) + : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))); + + /* Append RESTART. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x9 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) + | beginEndMark; + + buffer[1] + = FetchAddress; + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the RESTART command. */ + *Bytes = 8; + } + } + else + { + return gcvSTATUS_NOT_SUPPORTED; + } + + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGCOMMAND_FetchCommand +** +** Form a FETCH command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to an gckVGCOMMAND object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** FETCH command at or gcvNULL to query the size of the command. +** +** gctUINT32 FetchAddress +** The address of another command buffer to be executed by this FETCH +** command. If 'Logical' is gcvNULL, this argument is ignored. +** +** gctUINT FetchCount +** The number of 64-bit data quantities in another command buffer to +** be executed by this FETCH command. If 'Logical' is gcvNULL, this +** argument is ignored. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the FETCH command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the FETCH command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_FetchCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctUINT32 FetchAddress, + IN gctUINT FetchCount, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x", + Command, Logical, FetchAddress, FetchCount, Bytes); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append FETCH. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x5 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))); + + buffer[1] + = gcmFIXADDRESS(FetchAddress); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the FETCH command. */ + *Bytes = 8; + } + } + else + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append LINK. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + buffer[1] + = gcmFIXADDRESS(FetchAddress); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the LINK command. */ + *Bytes = 8; + } + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGCOMMAND_CallCommand +** +** Append a CALL command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to an gckVGCOMMAND object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** CALL command at or gcvNULL to query the size of the command. +** +** gctUINT32 FetchAddress +** The address of another command buffer to be executed by this CALL +** command. If 'Logical' is gcvNULL, this argument is ignored. +** +** gctUINT FetchCount +** The number of 64-bit data quantities in another command buffer to +** be executed by this CALL command. If 'Logical' is gcvNULL, this +** argument is ignored. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the CALL command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the CALL command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_CallCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctUINT32 FetchAddress, + IN gctUINT FetchCount, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x", + Command, Logical, FetchAddress, FetchCount, Bytes); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append CALL. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x6 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))); + + buffer[1] + = gcmFIXADDRESS(FetchAddress); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the CALL command. */ + *Bytes = 8; + } + } + else + { + return gcvSTATUS_NOT_SUPPORTED; + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGCOMMAND_ReturnCommand +** +** Append a RETURN command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to an gckVGCOMMAND object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** RETURN command at or gcvNULL to query the size of the command. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the RETURN command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the RETURN command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_ReturnCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x", + Command, Logical, Bytes); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append RETURN. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x7 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the RETURN command. */ + *Bytes = 8; + } + } + else + { + gcmkFOOTER_NO(); + return gcvSTATUS_NOT_SUPPORTED; + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGCOMMAND_EventCommand +** +** Form an EVENT command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to the Command object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** EVENT command at or gcvNULL to query the size of the command. +** +** gctINT32 InterruptId +** The ID of the interrupt to generate. +** If 'Logical' is gcvNULL, this argument is ignored. +** +** gceBLOCK Block +** Block that will generate the interrupt. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the EVENT command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the END command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_EventCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gceBLOCK Block, + IN gctINT32 InterruptId, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x", + Command, Logical, Block, InterruptId, Bytes); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + typedef struct _gcsEVENTSTATES + { + /* Chips before VG21 use these values. */ + gctUINT eventFromFE; + gctUINT eventFromPE; + + /* VG21 chips and later use SOURCE field. */ + gctUINT eventSource; + } + gcsEVENTSTATES; + + static gcsEVENTSTATES states[] = + { + /* gcvBLOCK_COMMAND */ + { + (gctUINT)~0, + (gctUINT)~0, + (gctUINT)~0 + }, + + /* gcvBLOCK_TESSELLATOR */ + { + 0x0, + 0x1, + 0x10 + }, + + /* gcvBLOCK_TESSELLATOR2 */ + { + 0x0, + 0x1, + 0x12 + }, + + /* gcvBLOCK_TESSELLATOR3 */ + { + 0x0, + 0x1, + 0x14 + }, + + /* gcvBLOCK_RASTER */ + { + 0x0, + 0x1, + 0x07, + }, + + /* gcvBLOCK_VG */ + { + 0x0, + 0x1, + 0x0F + }, + + /* gcvBLOCK_VG2 */ + { + 0x0, + 0x1, + 0x11 + }, + + /* gcvBLOCK_VG3 */ + { + 0x0, + 0x1, + 0x13 + }, + + /* gcvBLOCK_PIXEL */ + { + 0x0, + 0x1, + 0x07 + }, + }; + + /* Verify block ID. */ + gcmkVERIFY_ARGUMENT(gcmIS_VALID_INDEX(Block, states)); + + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Verify the event ID. */ + gcmkVERIFY_ARGUMENT(InterruptId >= 0); + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1)))))); + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append EVENT. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12))); + + /* Determine chip version. */ + if (Command->vg21) + { + /* Get the event source for the block. */ + gctUINT eventSource = states[Block].eventSource; + + /* Supported? */ + if (eventSource == ~0) + { + return gcvSTATUS_NOT_SUPPORTED; + } + + buffer[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) ((gctUINT32) (eventSource) & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + } + else + { + /* Get the event source for the block. */ + gctUINT eventFromFE = states[Block].eventFromFE; + gctUINT eventFromPE = states[Block].eventFromPE; + + /* Supported? */ + if (eventFromFE == ~0) + { + return gcvSTATUS_NOT_SUPPORTED; + } + + buffer[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (eventFromFE) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (eventFromPE) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + } + } + + if (Bytes != gcvNULL) + { + /* Make sure the events are directly supported for the block. */ + if (states[Block].eventSource == ~0) + { + return gcvSTATUS_NOT_SUPPORTED; + } + + /* Return number of bytes required by the END command. */ + *Bytes = 8; + } + } + else + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Verify the event ID. */ + gcmkVERIFY_ARGUMENT(InterruptId >= 0); + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1)))))); + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append EVENT. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + /* Determine event source. */ + if (Block == gcvBLOCK_COMMAND) + { + buffer[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); + } + else + { + buffer[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + } + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the EVENT and END commands. */ + *Bytes = 8; + } + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGCOMMAND_EndCommand +** +** Form an END command at the specified location in the command buffer. +** +** INPUT: +** +** gckVGCOMMAND Command +** Pointer to the Command object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command buffer to append +** END command at or gcvNULL to query the size of the command. +** +** gctINT32 InterruptId +** The ID of the interrupt to generate. +** If 'Logical' is gcvNULL, this argument will be ignored. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the END command. +** If 'Logical' is gcvNULL, the value from this argument is ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the END command. If 'Bytes' is gcvNULL, nothing is returned. +*/ +gceSTATUS +gckVGCOMMAND_EndCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctINT32 InterruptId, + IN OUT gctSIZE_T * Bytes + ) +{ + gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x", + Command, Logical, InterruptId, Bytes); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); + + if (Command->fe20) + { + if (Logical != gcvNULL) + { + gctUINT32_PTR buffer; + + /* Verify the event ID. */ + gcmkVERIFY_ARGUMENT(InterruptId >= 0); + + /* Cast the buffer pointer. */ + buffer = (gctUINT32_PTR) Logical; + + /* Append END. */ + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the END command. */ + *Bytes = 8; + } + } + else + { + if (Logical != gcvNULL) + { + gctUINT32_PTR memory; + + /* Verify the event ID. */ + gcmkVERIFY_ARGUMENT(InterruptId >= 0); + + /* Cast the buffer pointer. */ + memory = (gctUINT32_PTR) Logical; + + /* Append EVENT. */ + memory[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + memory[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + + /* Append END. */ + memory[2] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the EVENT and END commands. */ + *Bytes = 16; + } + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +#endif /* gcdENABLE_VG */ + diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h new file mode 100644 index 000000000000..a3738fe47b60 --- /dev/null +++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h @@ -0,0 +1,316 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2011 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + + + + + +#ifndef __gc_hal_kernel_hardware_command_vg_h_ +#define __gc_hal_kernel_hardware_command_vg_h_ + +/******************************************************************************\ +******************* Task and Interrupt Management Structures. ****************** +\******************************************************************************/ + +/* Task storage header. */ +typedef struct _gcsTASK_STORAGE * gcsTASK_STORAGE_PTR; +typedef struct _gcsTASK_STORAGE +{ + /* Next allocated storage buffer. */ + gcsTASK_STORAGE_PTR next; +} +gcsTASK_STORAGE; + +/* Task container header. */ +typedef struct _gcsTASK_CONTAINER * gcsTASK_CONTAINER_PTR; +typedef struct _gcsTASK_CONTAINER +{ + /* The number of tasks left to be processed in the container. */ + gctINT referenceCount; + + /* Size of the buffer. */ + gctUINT size; + + /* Link to the previous and the next allocated containers. */ + gcsTASK_CONTAINER_PTR allocPrev; + gcsTASK_CONTAINER_PTR allocNext; + + /* Link to the previous and the next containers in the free list. */ + gcsTASK_CONTAINER_PTR freePrev; + gcsTASK_CONTAINER_PTR freeNext; +} +gcsTASK_CONTAINER; + +/* Kernel space task master table entry. */ +typedef struct _gcsBLOCK_TASK_ENTRY * gcsBLOCK_TASK_ENTRY_PTR; +typedef struct _gcsBLOCK_TASK_ENTRY +{ + /* Pointer to the current task container for the block. */ + gcsTASK_CONTAINER_PTR container; + + /* Pointer to the current task data within the container. */ + gcsTASK_HEADER_PTR task; + + /* Pointer to the last link task within the container. */ + gcsTASK_LINK_PTR link; + + /* Number of interrupts allocated for this block. */ + gctUINT interruptCount; + + /* The index of the current interrupt. */ + gctUINT interruptIndex; + + /* Interrupt semaphore. */ + gctSEMAPHORE interruptSemaphore; + + /* Interrupt value array. */ + gctINT32 interruptArray[32]; +} +gcsBLOCK_TASK_ENTRY; + + +/******************************************************************************\ +********************* Command Queue Management Structures. ********************* +\******************************************************************************/ + +/* Command queue kernel element pointer. */ +typedef struct _gcsKERNEL_CMDQUEUE * gcsKERNEL_CMDQUEUE_PTR; + +/* Command queue object handler function type. */ +typedef gceSTATUS (* gctOBJECT_HANDLER) ( + gckVGKERNEL Kernel, + gcsKERNEL_CMDQUEUE_PTR Entry + ); + +/* Command queue kernel element. */ +typedef struct _gcsKERNEL_CMDQUEUE +{ + /* The number of buffers in the queue. */ + gcsCMDBUFFER_PTR commandBuffer; + + /* Pointer to the object handler function. */ + gctOBJECT_HANDLER handler; +} +gcsKERNEL_CMDQUEUE; + +/* Command queue header. */ +typedef struct _gcsKERNEL_QUEUE_HEADER * gcsKERNEL_QUEUE_HEADER_PTR; +typedef struct _gcsKERNEL_QUEUE_HEADER +{ + /* The size of the buffer in bytes. */ + gctUINT size; + + /* The number of pending entries to be processed. */ + volatile gctUINT pending; + + /* The current command queue entry. */ + gcsKERNEL_CMDQUEUE_PTR currentEntry; + + /* Next buffer. */ + gcsKERNEL_QUEUE_HEADER_PTR next; +} +gcsKERNEL_QUEUE_HEADER; + + +/******************************************************************************\ +******************************* gckVGCOMMAND Object ******************************* +\******************************************************************************/ + +/* gckVGCOMMAND object. */ +struct _gckVGCOMMAND +{ + /*************************************************************************** + ** Object data and pointers. + */ + + gcsOBJECT object; + gckVGKERNEL kernel; + gckOS os; + gckVGHARDWARE hardware; + + /* Features. */ + gctBOOL fe20; + gctBOOL vg20; + gctBOOL vg21; + + + /*************************************************************************** + ** Enable command queue dumping. + */ + + gctBOOL enableDumping; + + + /*************************************************************************** + ** Bus Error interrupt. + */ + + gctINT32 busErrorInt; + + + /*************************************************************************** + ** Command buffer information. + */ + + gcsCOMMAND_BUFFER_INFO info; + + + /*************************************************************************** + ** Synchronization objects. + */ + + gctPOINTER queueMutex; + gctPOINTER taskMutex; + gctPOINTER commitMutex; + + + /*************************************************************************** + ** Task management. + */ + + /* The head of the storage buffer linked list. */ + gcsTASK_STORAGE_PTR taskStorage; + + /* Allocation size. */ + gctUINT taskStorageGranularity; + gctUINT taskStorageUsable; + + /* The free container list. */ + gcsTASK_CONTAINER_PTR taskFreeHead; + gcsTASK_CONTAINER_PTR taskFreeTail; + + /* Task table */ + gcsBLOCK_TASK_ENTRY taskTable[gcvBLOCK_COUNT]; + + + /*************************************************************************** + ** Command queue. + */ + + /* Pointer to the allocated queue memory. */ + gcsKERNEL_QUEUE_HEADER_PTR queue; + + /* Pointer to the current available queue from which new queue entries + will be allocated. */ + gcsKERNEL_QUEUE_HEADER_PTR queueHead; + + /* If different from queueHead, points to the command queue which is + currently being executed by the hardware. */ + gcsKERNEL_QUEUE_HEADER_PTR queueTail; + + /* Points to the queue to merge the tail with when the tail is processed. */ + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue; + + /* Queue overflow counter. */ + gctUINT queueOverflow; + + + /*************************************************************************** + ** Context. + */ + + /* Context counter used for unique ID. */ + gctUINT64 contextCounter; + + /* Current context ID. */ + gctUINT64 currentContext; +}; + +/******************************************************************************\ +************************ gckVGCOMMAND Object Internal API. *********************** +\******************************************************************************/ + +/* Initialize architecture dependent command buffer information. */ +gceSTATUS +gckVGCOMMAND_InitializeInfo( + IN gckVGCOMMAND Command + ); + +/* Form a STATE command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_StateCommand( + IN gckVGCOMMAND Command, + IN gctUINT32 Pipe, + IN gctPOINTER Logical, + IN gctUINT32 Address, + IN gctSIZE_T Count, + IN OUT gctSIZE_T * Bytes + ); + +/* Form a RESTART command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_RestartCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctUINT32 FetchAddress, + IN gctUINT FetchCount, + IN OUT gctSIZE_T * Bytes + ); + +/* Form a FETCH command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_FetchCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctUINT32 FetchAddress, + IN gctUINT FetchCount, + IN OUT gctSIZE_T * Bytes + ); + +/* Form a CALL command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_CallCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctUINT32 FetchAddress, + IN gctUINT FetchCount, + IN OUT gctSIZE_T * Bytes + ); + +/* Form a RETURN command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_ReturnCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN OUT gctSIZE_T * Bytes + ); + +/* Form an EVENT command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_EventCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gceBLOCK Block, + IN gctINT32 InterruptId, + IN OUT gctSIZE_T * Bytes + ); + +/* Form an END command at the specified location in the command buffer. */ +gceSTATUS +gckVGCOMMAND_EndCommand( + IN gckVGCOMMAND Command, + IN gctPOINTER Logical, + IN gctINT32 InterruptId, + IN OUT gctSIZE_T * Bytes + ); + +#endif /* __gc_hal_kernel_hardware_command_h_ */ + diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c new file mode 100644 index 000000000000..b5cd03572734 --- /dev/null +++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c @@ -0,0 +1,1216 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2011 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + + + +#include "gc_hal.h" +#include "gc_hal_kernel.h" + +#if gcdENABLE_VG + +#define _GC_OBJ_ZONE gcvZONE_HARDWARE + +/******************************************************************************\ +********************************* Support Code ********************************* +\******************************************************************************/ + +static gceSTATUS +_IdentifyHardware( + IN gckOS Os, + OUT gceCHIPMODEL * ChipModel, + OUT gctUINT32 * ChipRevision, + OUT gctUINT32 * ChipFeatures, + OUT gctUINT32 * ChipMinorFeatures, + OUT gctUINT32 * ChipMinorFeatures2 + ) +{ + gceSTATUS status; + gctUINT32 chipIdentity; + + do + { + /* Read chip identity register. */ + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, 0x00018, &chipIdentity)); + + /* Special case for older graphic cores. */ + if (((((gctUINT32) (chipIdentity)) >> (0 ? 31:24) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))))) + { + *ChipModel = gcv500; + *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) ); + } + + else + { + /* Read chip identity register. */ + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, + 0x00020, + (gctUINT32 *) ChipModel)); + + /* Read CHIP_REV register. */ + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, + 0x00024, + ChipRevision)); + } + + /* Read chip feature register. */ + gcmkERR_BREAK(gckOS_ReadRegisterEx( + Os, gcvCORE_VG, 0x0001C, ChipFeatures + )); + + /* Read chip minor feature register. */ + gcmkERR_BREAK(gckOS_ReadRegisterEx( + Os, gcvCORE_VG, 0x00034, ChipMinorFeatures + )); + + /* Read chip minor feature register #2. */ + gcmkERR_BREAK(gckOS_ReadRegisterEx( + Os, gcvCORE_VG, 0x00074, ChipMinorFeatures2 + )); + + gcmkTRACE( + gcvLEVEL_VERBOSE, + "ChipModel=0x%08X\n" + "ChipRevision=0x%08X\n" + "ChipFeatures=0x%08X\n" + "ChipMinorFeatures=0x%08X\n" + "ChipMinorFeatures2=0x%08X\n", + *ChipModel, + *ChipRevision, + *ChipFeatures, + *ChipMinorFeatures, + *ChipMinorFeatures2 + ); + + /* Success. */ + return gcvSTATUS_OK; + } + while (gcvFALSE); + + /* Return the status. */ + return status; +} + +/******************************************************************************\ +****************************** gckVGHARDWARE API code ***************************** +\******************************************************************************/ + +/******************************************************************************* +** +** gckVGHARDWARE_Construct +** +** Construct a new gckVGHARDWARE object. +** +** INPUT: +** +** gckOS Os +** Pointer to an initialized gckOS object. +** +** OUTPUT: +** +** gckVGHARDWARE * Hardware +** Pointer to a variable that will hold the pointer to the gckVGHARDWARE +** object. +*/ +gceSTATUS +gckVGHARDWARE_Construct( + IN gckOS Os, + OUT gckVGHARDWARE * Hardware + ) +{ + gckVGHARDWARE hardware; + gceSTATUS status; + gceCHIPMODEL chipModel; + gctUINT32 chipRevision; + gctUINT32 chipFeatures; + gctUINT32 chipMinorFeatures; + gctUINT32 chipMinorFeatures2; + + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x ", Os, Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL); + + do + { + /* Identify the hardware. */ + gcmkERR_BREAK(_IdentifyHardware(Os, + &chipModel, &chipRevision, + &chipFeatures, &chipMinorFeatures, &chipMinorFeatures2 + )); + + /* Allocate the gckVGHARDWARE object. */ + gcmkERR_BREAK(gckOS_Allocate(Os, + gcmSIZEOF(struct _gckVGHARDWARE), (gctPOINTER *) &hardware + )); + + /* Initialize the gckVGHARDWARE object. */ + hardware->object.type = gcvOBJ_HARDWARE; + hardware->os = Os; + + /* Set chip identity. */ + hardware->chipModel = chipModel; + hardware->chipRevision = chipRevision; + hardware->chipFeatures = chipFeatures; + hardware->chipMinorFeatures = chipMinorFeatures; + hardware->chipMinorFeatures2 = chipMinorFeatures2; + + /* Determine whether FE 2.0 is present. */ + hardware->fe20 = ((((gctUINT32) (hardware->chipFeatures)) >> (0 ? 28:28) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1))))))); + + /* Determine whether VG 2.0 is present. */ + hardware->vg20 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ? 13:13) & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))); + + /* Determine whether VG 2.1 is present. */ + hardware->vg21 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))); + + /* Set default event mask. */ + hardware->eventMask = 0xFFFFFFFF; + + /* Set fast clear to auto. */ + gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1)); + + /* Return pointer to the gckVGHARDWARE object. */ + *Hardware = hardware; + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; + } + while (gcvFALSE); + + gcmkFOOTER(); + /* Return the status. */ + return status; +} + +/******************************************************************************* +** +** gckVGHARDWARE_Destroy +** +** Destroy an gckVGHARDWARE object. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to the gckVGHARDWARE object that needs to be destroyed. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckVGHARDWARE_Destroy( + IN gckVGHARDWARE Hardware + ) +{ + gceSTATUS status; + gcmkHEADER_ARG("Hardware=0x%x ", Hardware); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Mark the object as unknown. */ + Hardware->object.type = gcvOBJ_UNKNOWN; + + /* Free the object. */ + status = gckOS_Free(Hardware->os, Hardware); + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckVGHARDWARE_QueryMemory +** +** Query the amount of memory available on the hardware. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to the gckVGHARDWARE object. +** +** OUTPUT: +** +** gctSIZE_T * InternalSize +** Pointer to a variable that will hold the size of the internal video +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the +** internal memory will be returned. +** +** gctUINT32 * InternalBaseAddress +** Pointer to a variable that will hold the hardware's base address for +** the internal video memory. This pointer cannot be gcvNULL if +** 'InternalSize' is also non-gcvNULL. +** +** gctUINT32 * InternalAlignment +** Pointer to a variable that will hold the hardware's base address for +** the internal video memory. This pointer cannot be gcvNULL if +** 'InternalSize' is also non-gcvNULL. +** +** gctSIZE_T * ExternalSize +** Pointer to a variable that will hold the size of the external video +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the +** external memory will be returned. +** +** gctUINT32 * ExternalBaseAddress +** Pointer to a variable that will hold the hardware's base address for +** the external video memory. This pointer cannot be gcvNULL if +** 'ExternalSize' is also non-gcvNULL. +** +** gctUINT32 * ExternalAlignment +** Pointer to a variable that will hold the hardware's base address for +** the external video memory. This pointer cannot be gcvNULL if +** 'ExternalSize' is also non-gcvNULL. +** +** gctUINT32 * HorizontalTileSize +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is +** gcvNULL, no horizontal pixel per tile will be returned. +** +** gctUINT32 * VerticalTileSize +** Number of vertical pixels per tile. If 'VerticalTileSize' is +** gcvNULL, no vertical pixel per tile will be returned. +*/ +gceSTATUS +gckVGHARDWARE_QueryMemory( + IN gckVGHARDWARE Hardware, + OUT gctSIZE_T * InternalSize, + OUT gctUINT32 * InternalBaseAddress, + OUT gctUINT32 * InternalAlignment, + OUT gctSIZE_T * ExternalSize, + OUT gctUINT32 * ExternalBaseAddress, + OUT gctUINT32 * ExternalAlignment, + OUT gctUINT32 * HorizontalTileSize, + OUT gctUINT32 * VerticalTileSize + ) +{ + gcmkHEADER_ARG("Hardware=0x%x InternalSize=0x%x InternalBaseAddress=0x%x InternalAlignment=0x%x" + "ExternalSize=0x%x ExternalBaseAddress=0x%x ExternalAlignment=0x%x HorizontalTileSize=0x%x VerticalTileSize=0x%x", + Hardware, InternalSize, InternalBaseAddress, InternalAlignment, + ExternalSize, ExternalBaseAddress, ExternalAlignment, HorizontalTileSize, VerticalTileSize); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (InternalSize != gcvNULL) + { + /* No internal memory. */ + *InternalSize = 0; + } + + if (ExternalSize != gcvNULL) + { + /* No external memory. */ + *ExternalSize = 0; + } + + if (HorizontalTileSize != gcvNULL) + { + /* 4x4 tiles. */ + *HorizontalTileSize = 4; + } + + if (VerticalTileSize != gcvNULL) + { + /* 4x4 tiles. */ + *VerticalTileSize = 4; + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGHARDWARE_QueryChipIdentity +** +** Query the identity of the hardware. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to the gckVGHARDWARE object. +** +** OUTPUT: +** +** gceCHIPMODEL * ChipModel +** If 'ChipModel' is not gcvNULL, the variable it points to will +** receive the model of the chip. +** +** gctUINT32 * ChipRevision +** If 'ChipRevision' is not gcvNULL, the variable it points to will +** receive the revision of the chip. +** +** gctUINT32 * ChipFeatures +** If 'ChipFeatures' is not gcvNULL, the variable it points to will +** receive the feature set of the chip. +** +** gctUINT32 * ChipMinorFeatures +** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to +** will receive the minor feature set of the chip. +** +** gctUINT32 * ChipMinorFeatures2 +** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to +** will receive the minor feature set of the chip. +** +*/ +gceSTATUS +gckVGHARDWARE_QueryChipIdentity( + IN gckVGHARDWARE Hardware, + OUT gceCHIPMODEL * ChipModel, + OUT gctUINT32 * ChipRevision, + OUT gctUINT32* ChipFeatures, + OUT gctUINT32* ChipMinorFeatures, + OUT gctUINT32* ChipMinorFeatures2 + ) +{ + gcmkHEADER_ARG("Hardware=0x%x ChipModel=0x%x ChipRevision=0x%x ChipFeatures = 0x%x ChipMinorFeatures = 0x%x ChipMinorFeatures2 = 0x%x", + Hardware, ChipModel, ChipRevision, ChipFeatures, ChipMinorFeatures, ChipMinorFeatures2); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Return chip model. */ + if (ChipModel != gcvNULL) + { + *ChipModel = Hardware->chipModel; + } + + /* Return revision number. */ + if (ChipRevision != gcvNULL) + { + *ChipRevision = Hardware->chipRevision; + } + + /* Return feature set. */ + if (ChipFeatures != gcvNULL) + { + gctUINT32 features = Hardware->chipFeatures; + + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + { + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Hardware->allowFastClear) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + } + + /* Mark 2D pipe as available for GC500.0 since it did not have this *\ + \* bit. */ + if ((Hardware->chipModel == gcv500) + && (Hardware->chipRevision == 0) + ) + { + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))); + } + + /* Mark 2D pipe as available for GC300 since it did not have this *\ + \* bit. */ + if (Hardware->chipModel == gcv300) + { + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))); + } + + *ChipFeatures = features; + } + + /* Return minor feature set. */ + if (ChipMinorFeatures != gcvNULL) + { + *ChipMinorFeatures = Hardware->chipMinorFeatures; + } + + /* Return minor feature set #2. */ + if (ChipMinorFeatures2 != gcvNULL) + { + *ChipMinorFeatures2 = Hardware->chipMinorFeatures2; + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGHARDWARE_ConvertFormat +** +** Convert an API format to hardware parameters. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to the gckVGHARDWARE object. +** +** gceSURF_FORMAT Format +** API format to convert. +** +** OUTPUT: +** +** gctUINT32 * BitsPerPixel +** Pointer to a variable that will hold the number of bits per pixel. +** +** gctUINT32 * BytesPerTile +** Pointer to a variable that will hold the number of bytes per tile. +*/ +gceSTATUS +gckVGHARDWARE_ConvertFormat( + IN gckVGHARDWARE Hardware, + IN gceSURF_FORMAT Format, + OUT gctUINT32 * BitsPerPixel, + OUT gctUINT32 * BytesPerTile + ) +{ + gctUINT32 bitsPerPixel; + gctUINT32 bytesPerTile; + + gcmkHEADER_ARG("Hardware=0x%x Format=0x%x BitsPerPixel=0x%x BytesPerTile = 0x%x", + Hardware, Format, BitsPerPixel, BytesPerTile); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Dispatch on format. */ + switch (Format) + { + case gcvSURF_A1: + case gcvSURF_L1: + /* 1-bpp format. */ + bitsPerPixel = 1; + bytesPerTile = (1 * 4 * 4) / 8; + break; + + case gcvSURF_A4: + /* 4-bpp format. */ + bitsPerPixel = 4; + bytesPerTile = (4 * 4 * 4) / 8; + break; + + case gcvSURF_INDEX8: + case gcvSURF_A8: + case gcvSURF_L8: + /* 8-bpp format. */ + bitsPerPixel = 8; + bytesPerTile = (8 * 4 * 4) / 8; + break; + + case gcvSURF_YV12: + /* 12-bpp planar YUV formats. */ + bitsPerPixel = 12; + bytesPerTile = (12 * 4 * 4) / 8; + break; + + case gcvSURF_NV12: + /* 12-bpp planar YUV formats. */ + bitsPerPixel = 12; + bytesPerTile = (12 * 4 * 4) / 8; + break; + + /* 4444 variations. */ + case gcvSURF_X4R4G4B4: + case gcvSURF_A4R4G4B4: + case gcvSURF_R4G4B4X4: + case gcvSURF_R4G4B4A4: + case gcvSURF_B4G4R4X4: + case gcvSURF_B4G4R4A4: + case gcvSURF_X4B4G4R4: + case gcvSURF_A4B4G4R4: + + /* 1555 variations. */ + case gcvSURF_X1R5G5B5: + case gcvSURF_A1R5G5B5: + case gcvSURF_R5G5B5X1: + case gcvSURF_R5G5B5A1: + case gcvSURF_X1B5G5R5: + case gcvSURF_A1B5G5R5: + case gcvSURF_B5G5R5X1: + case gcvSURF_B5G5R5A1: + + /* 565 variations. */ + case gcvSURF_R5G6B5: + case gcvSURF_B5G6R5: + + case gcvSURF_A8L8: + case gcvSURF_YUY2: + case gcvSURF_UYVY: + case gcvSURF_D16: + /* 16-bpp format. */ + bitsPerPixel = 16; + bytesPerTile = (16 * 4 * 4) / 8; + break; + + case gcvSURF_X8R8G8B8: + case gcvSURF_A8R8G8B8: + case gcvSURF_X8B8G8R8: + case gcvSURF_A8B8G8R8: + case gcvSURF_R8G8B8X8: + case gcvSURF_R8G8B8A8: + case gcvSURF_B8G8R8X8: + case gcvSURF_B8G8R8A8: + case gcvSURF_D32: + /* 32-bpp format. */ + bitsPerPixel = 32; + bytesPerTile = (32 * 4 * 4) / 8; + break; + + case gcvSURF_D24S8: + /* 24-bpp format. */ + bitsPerPixel = 32; + bytesPerTile = (32 * 4 * 4) / 8; + break; + + case gcvSURF_DXT1: + case gcvSURF_ETC1: + bitsPerPixel = 4; + bytesPerTile = (4 * 4 * 4) / 8; + break; + + case gcvSURF_DXT2: + case gcvSURF_DXT3: + case gcvSURF_DXT4: + case gcvSURF_DXT5: + bitsPerPixel = 8; + bytesPerTile = (8 * 4 * 4) / 8; + break; + + default: + /* Invalid format. */ + return gcvSTATUS_INVALID_ARGUMENT; + } + + /* Set the result. */ + if (BitsPerPixel != gcvNULL) + { + * BitsPerPixel = bitsPerPixel; + } + + if (BytesPerTile != gcvNULL) + { + * BytesPerTile = bytesPerTile; + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGHARDWARE_SplitMemory +** +** Split a hardware specific memory address into a pool and offset. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to the gckVGHARDWARE object. +** +** gctUINT32 Address +** Address in hardware specific format. +** +** OUTPUT: +** +** gcePOOL * Pool +** Pointer to a variable that will hold the pool type for the address. +** +** gctUINT32 * Offset +** Pointer to a variable that will hold the offset for the address. +*/ +gceSTATUS +gckVGHARDWARE_SplitMemory( + IN gckVGHARDWARE Hardware, + IN gctUINT32 Address, + OUT gcePOOL * Pool, + OUT gctUINT32 * Offset + ) +{ + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Pool=0x%x Offset = 0x%x", + Hardware, Address, Pool, Offset); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Pool != gcvNULL); + gcmkVERIFY_ARGUMENT(Offset != gcvNULL); + + /* Dispatch on memory type. */ + switch ((((((gctUINT32) (Address)) >> (0 ? 1:0)) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1)))))) )) + { + case 0x0: + /* System memory. */ + *Pool = gcvPOOL_SYSTEM; + break; + + case 0x2: + /* Virtual memory. */ + *Pool = gcvPOOL_VIRTUAL; + break; + + default: + /* Invalid memory type. */ + return gcvSTATUS_INVALID_ARGUMENT; + } + + /* Return offset of address. */ + *Offset = ((((gctUINT32) (Address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))); + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGHARDWARE_Execute +** +** Kickstart the hardware's command processor with an initialized command +** buffer. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to the gckVGHARDWARE object. +** +** gctUINT32 Address +** Address of the command buffer. +** +** gctSIZE_T Count +** Number of command-sized data units to be executed. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckVGHARDWARE_Execute( + IN gckVGHARDWARE Hardware, + IN gctUINT32 Address, + IN gctSIZE_T Count + ) +{ + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Count=0x%x", + Hardware, Address, Count); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + do + { + /* Enable all events. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx( + Hardware->os, + gcvCORE_VG, + 0x00014, + Hardware->eventMask + )); + + if (Hardware->fe20) + { + /* Write address register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx( + Hardware->os, + gcvCORE_VG, + 0x00500, + gcmFIXADDRESS(Address) + )); + + /* Write control register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx( + Hardware->os, + gcvCORE_VG, + 0x00504, + Count + )); + } + else + { + /* Write address register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx( + Hardware->os, + gcvCORE_VG, + 0x00654, + gcmFIXADDRESS(Address) + )); + + /* Write control register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx( + Hardware->os, + gcvCORE_VG, + 0x00658, + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + )); + } + + /* Success. */ + return gcvSTATUS_OK; + } + while (gcvFALSE); + + + gcmkFOOTER(); + /* Return the status. */ + return status; +} + +/******************************************************************************* +** +** gckVGHARDWARE_AlignToTile +** +** Align the specified width and height to tile boundaries. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to an gckVGHARDWARE object. +** +** gceSURF_TYPE Type +** Type of alignment. +** +** gctUINT32 * Width +** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width +** will be aligned. +** +** gctUINT32 * Height +** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height +** will be aligned. +** +** OUTPUT: +** +** gctUINT32 * Width +** Pointer to a variable that will receive the aligned width. +** +** gctUINT32 * Height +** Pointer to a variable that will receive the aligned height. +*/ +gceSTATUS +gckVGHARDWARE_AlignToTile( + IN gckVGHARDWARE Hardware, + IN gceSURF_TYPE Type, + IN OUT gctUINT32 * Width, + IN OUT gctUINT32 * Height + ) +{ + gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x", + Hardware, Type, Width, Height); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (Width != gcvNULL) + { + /* Align the width. */ + *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16); + } + + if (Height != gcvNULL) + { + /* Special case for VG images. */ + if ((*Height == 0) && (Type == gcvSURF_IMAGE)) + { + *Height = 4; + } + else + { + /* Align the height. */ + *Height = gcmALIGN(*Height, 4); + } + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGHARDWARE_ConvertLogical +** +** Convert a logical system address into a hardware specific address. +** +** INPUT: +** +** gckVGHARDWARE Hardware +** Pointer to an gckVGHARDWARE object. +** +** gctPOINTER Logical +** Logical address to convert. +** +** gctUINT32* Address +** Return hardware specific address. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckVGHARDWARE_ConvertLogical( + IN gckVGHARDWARE Hardware, + IN gctPOINTER Logical, + OUT gctUINT32 * Address + ) +{ + gctUINT32 address; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x", + Hardware, Logical, Address); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + gcmkVERIFY_ARGUMENT(Address != gcvNULL); + + do + { + /* Convert logical address into a physical address. */ + gcmkERR_BREAK(gckOS_GetPhysicalAddress( + Hardware->os, Logical, &address + )); + + /* Return hardware specific address. */ + *Address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))); + + /* Success. */ + return gcvSTATUS_OK; + } + while (gcvFALSE); + + gcmkFOOTER(); + /* Return the status. */ + return status; +} + +/******************************************************************************* +** +** gckVGHARDWARE_QuerySystemMemory +** +** Query the command buffer alignment and number of reserved bytes. +** +** INPUT: +** +** gckVGHARDWARE Harwdare +** Pointer to an gckVGHARDWARE object. +** +** OUTPUT: +** +** gctSIZE_T * SystemSize +** Pointer to a variable that receives the maximum size of the system +** memory. +** +** gctUINT32 * SystemBaseAddress +** Poinetr to a variable that receives the base address for system +** memory. +*/ +gceSTATUS gckVGHARDWARE_QuerySystemMemory( + IN gckVGHARDWARE Hardware, + OUT gctSIZE_T * SystemSize, + OUT gctUINT32 * SystemBaseAddress + ) +{ + gcmkHEADER_ARG("Hardware=0x%x SystemSize=0x%x SystemBaseAddress=0x%x", + Hardware, SystemSize, SystemBaseAddress); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (SystemSize != gcvNULL) + { + /* Maximum system memory can be 2GB. */ + *SystemSize = (gctSIZE_T)(1 << 31); + } + + if (SystemBaseAddress != gcvNULL) + { + /* Set system memory base address. */ + *SystemBaseAddress = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))); + } + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVGHARDWARE_SetMMU +** +** Set the page table base address. +** +** INPUT: +** +** gckVGHARDWARE Harwdare +** Pointer to an gckVGHARDWARE object. +** +** gctPOINTER Logical +** Logical address of the page table. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS gckVGHARDWARE_SetMMU( + IN gckVGHARDWARE Hardware, + IN gctPOINTER Logical + ) +{ + gceSTATUS status; + gctUINT32 address = 0; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", + Hardware, Logical); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + + do + { + /* Convert the logical address into an hardware address. */ + gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) ); + + /* Write the AQMemoryFePageTable register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, + 0x00400, + gcmFIXADDRESS(address)) ); + + /* Write the AQMemoryTxPageTable register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, + 0x00404, + gcmFIXADDRESS(address)) ); + + /* Write the AQMemoryPePageTable register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, + 0x00408, + gcmFIXADDRESS(address)) ); + + /* Write the AQMemoryPezPageTable register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, + 0x0040C, + gcmFIXADDRESS(address)) ); + + /* Write the AQMemoryRaPageTable register. */ + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, + 0x00410, + gcmFIXADDRESS(address)) ); + } + while (gcvFALSE); + + gcmkFOOTER(); + /* Return the status. */ + return status; +} + +/******************************************************************************* +** +** gckVGHARDWARE_FlushMMU +** +** Flush the page table. +** +** INPUT: +** +** gckVGHARDWARE Harwdare +** Pointer to an gckVGHARDWARE object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS gckVGHARDWARE_FlushMMU( + IN gckVGHARDWARE Hardware + ) +{ + gceSTATUS status; + gckVGCOMMAND command; + + gcmkHEADER_ARG("Hardware=0x%x ", Hardware); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + do + { + gcsCMDBUFFER_PTR commandBuffer; + gctUINT32_PTR buffer; + + /* Create a shortcut to the command buffer object. */ + command = Hardware->kernel->command; + + /* Allocate command buffer space. */ + gcmkERR_BREAK(gckVGCOMMAND_Allocate( + Hardware->kernel->command, 8, &commandBuffer, (gctPOINTER *) &buffer + )); + + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + buffer[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); + + gcmkERR_BREAK(gckVGCOMMAND_Execute( + Hardware->kernel->command, + commandBuffer + )); + } + while(gcvFALSE); + gcmkFOOTER(); + /* Return the status. */ + return status; +} + +/******************************************************************************* +** +** gckVGHARDWARE_BuildVirtualAddress +** +** Build a virtual address. +** +** INPUT: +** +** gckVGHARDWARE Harwdare +** Pointer to an gckVGHARDWARE object. +** +** gctUINT32 Index +** Index into page table. +** +** gctUINT32 Offset +** Offset into page. +** +** OUTPUT: +** +** gctUINT32 * Address +** Pointer to a variable receiving te hardware address. +*/ +gceSTATUS gckVGHARDWARE_BuildVirtualAddress( + IN gckVGHARDWARE Hardware, + IN gctUINT32 Index, + IN gctUINT32 Offset, + OUT gctUINT32 * Address + ) +{ + gctUINT32 address; + + gcmkHEADER_ARG("Hardware=0x%x Index=0x%x Offset=0x%x Address=0x%x", + Hardware, Index, Offset, Address); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Address != gcvNULL); + + /* Build virtual address. */ + address = (Index << 12) | Offset; + + /* Set virtual type. */ + address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))); + + /* Set the result. */ + *Address = address; + + gcmkFOOTER_NO(); + /* Success. */ + return gcvSTATUS_OK; +} + +gceSTATUS +gckVGHARDWARE_GetIdle( + IN gckVGHARDWARE Hardware, + OUT gctUINT32 * Data + ) +{ + gceSTATUS status; + gcmkHEADER_ARG("Hardware=0x%x Data=0x%x", Hardware, Data); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Data != gcvNULL); + + /* Read register and return. */ + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, Data); + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckVGHARDWARE_SetFastClear( + IN gckVGHARDWARE Hardware, + IN gctINT Enable + ) +{ + gctUINT32 debug; + gceSTATUS status; + + if (!(((((gctUINT32) (Hardware->chipFeatures)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + { + return gcvSTATUS_OK; + } + + do + { + if (Enable == -1) + { + Enable = (Hardware->chipModel > gcv500) || + ((Hardware->chipModel == gcv500) && (Hardware->chipRevision >= 3)); + } + + gcmkERR_BREAK(gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, + 0x00414, + &debug)); + + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))); + +#ifdef AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION))); +#endif + + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, + 0x00414, + debug)); + + Hardware->allowFastClear = Enable; + + status = gcvFALSE; + } + while (gcvFALSE); + + return status; +} + +gceSTATUS +gckVGHARDWARE_ReadInterrupt( + IN gckVGHARDWARE Hardware, + OUT gctUINT32_PTR IDs + ) +{ + gceSTATUS status; + gcmkHEADER_ARG("Hardware=0x%x IDs=0x%x", Hardware, IDs); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(IDs != gcvNULL); + + /* Read AQIntrAcknowledge register. */ + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, + 0x00010, + IDs); + gcmkFOOTER(); + return status; +} + +#endif /* gcdENABLE_VG */ + diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h new file mode 100644 index 000000000000..f7300bbb326c --- /dev/null +++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h @@ -0,0 +1,59 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2011 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + + + + + +#ifndef __gc_hal_kernel_hardware_vg_h_ +#define __gc_hal_kernel_hardware_vg_h_ + +/* gckHARDWARE object. */ +struct _gckVGHARDWARE +{ + /* Object. */ + gcsOBJECT object; + + /* Pointer to gckKERNEL object. */ + gckVGKERNEL kernel; + + /* Pointer to gckOS object. */ + gckOS os; + + /* Chip characteristics. */ + gceCHIPMODEL chipModel; + gctUINT32 chipRevision; + gctUINT32 chipFeatures; + gctUINT32 chipMinorFeatures; + gctUINT32 chipMinorFeatures2; + gctBOOL allowFastClear; + + /* Features. */ + gctBOOL fe20; + gctBOOL vg20; + gctBOOL vg21; + + /* Event mask. */ + gctUINT32 eventMask; +}; + +#endif /* __gc_hal_kernel_hardware_h_ */ + |