/****************************************************************************
*
*    The MIT License (MIT)
*
*    Copyright (c) 2014 - 2018 Vivante Corporation
*
*    Permission is hereby granted, free of charge, to any person obtaining a
*    copy of this software and associated documentation files (the "Software"),
*    to deal in the Software without restriction, including without limitation
*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
*    and/or sell copies of the Software, and to permit persons to whom the
*    Software is furnished to do so, subject to the following conditions:
*
*    The above copyright notice and this permission notice shall be included in
*    all copies or substantial portions of the Software.
*
*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
*    DEALINGS IN THE SOFTWARE.
*
*****************************************************************************
*
*    The GPL License (GPL)
*
*    Copyright (C) 2014 - 2018 Vivante Corporation
*
*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*****************************************************************************
*
*    Note: This software is released under dual MIT and GPL licenses. A
*    recipient may use this file under the terms of either the MIT license or
*    GPL License. If you wish to use only one license not the other, you can
*    indicate your decision by deleting one of the above license notices in your
*    version of this file.
*
*****************************************************************************/


#include "gc_hal_kernel_precomp.h"
#include "gc_hal_kernel_context.h"

#define _GC_OBJ_ZONE            gcvZONE_ASYNC_COMMAND

static gceSTATUS
_HandlePatchList(
    IN gckASYNC_COMMAND Command,
    IN gcoCMDBUF CommandBuffer,
    IN gctBOOL NeedCopy
    )
{
    gceSTATUS status;
    gcsPATCH_LIST * uList;
    gcsPATCH_LIST * previous;
    gcsPATCH_LIST * kList;

    gcmkHEADER_ARG(
        "Command=0x%x CommandBuffer=0x%x NeedCopy=%d",
        Command, CommandBuffer, NeedCopy
        );

    uList = gcmUINT64_TO_PTR(CommandBuffer->patchHead);

    while (uList)
    {
        gctUINT i;

        kList = gcvNULL;
        previous = uList;

        gcmkONERROR(gckKERNEL_OpenUserData(
            Command->kernel,
            NeedCopy,
            Command->kList,
            uList,
            gcmSIZEOF(gcsPATCH_LIST),
            (gctPOINTER *)&kList
            ));

        for (i = 0; i < kList->count; i++)
        {
            gcsPATCH * patch = &kList->patch[i];

            /* Touch video memory node. */
            gcmkVERIFY_OK(gckVIDMEM_SetCommitStamp(Command->kernel, gcvENGINE_BLT, patch->handle, Command->commitStamp));
        }

        uList = kList->next;

        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
            Command->kernel,
            NeedCopy,
            gcvFALSE,
            previous,
            gcmSIZEOF(gcsPATCH_LIST),
            (gctPOINTER *)&kList
            ));
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    if (kList)
    {
        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
            Command->kernel,
            NeedCopy,
            gcvFALSE,
            previous,
            gcmSIZEOF(gcsPATCH_LIST),
            (gctPOINTER *)&kList
            ));
    }

    gcmkFOOTER();
    return status;
}


gceSTATUS
gckASYNC_COMMAND_Construct(
    IN gckKERNEL Kernel,
    OUT gckASYNC_COMMAND * Command
    )
{
    gceSTATUS status;
    gckASYNC_COMMAND command;
    gckOS os = Kernel->os;

    gcmkHEADER();

    /* Allocate gckASYNC_COMMAND object. */
    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsASYNC_COMMAND), (gctPOINTER *)&command));

    gckOS_ZeroMemory(command, gcmSIZEOF(gcsASYNC_COMMAND));

    /* Mutex to protect gckFE. */
    gcmkONERROR(gckOS_CreateMutex(os, &command->mutex));

    /* Initialize gckFE. */
    gckFE_Initialize(Kernel->hardware, &command->fe);

    /* Initialize gckASYNC_COMMAND object. */
    command->os = os;
    command->kernel = Kernel;
    command->hardware = Kernel->hardware;

    gcmkVERIFY_OK(gckHARDWARE_QueryCommandBuffer(
        Kernel->hardware,
        gcvENGINE_BLT,
        gcvNULL,
        gcvNULL,
        &command->reservedTail
        ));

    gcmkONERROR(gckFENCE_Create(
        os, Kernel, &command->fence
        ));

    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsPATCH_LIST), &command->kList));

    /* Commit stamp start from 1. */
    command->commitStamp = 1;

    *Command = command;

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Rollback. */
    gckASYNC_COMMAND_Destroy(command);

    gcmkFOOTER();
    return status;
}

gceSTATUS
gckASYNC_COMMAND_Destroy(
    IN gckASYNC_COMMAND Command
    )
{
    gcmkHEADER();

    if (Command)
    {
        if (Command->mutex)
        {
            gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutex));
        }

        if (Command->fence)
        {
            gcmkVERIFY_OK(gckFENCE_Destory(Command->os, Command->fence));
        }

        if (Command->kList)
        {
            gcmkOS_SAFE_FREE(Command->os, Command->kList);
        }

        if (Command->fe.freeDscriptors)
        {
            gcmkOS_SAFE_FREE(Command->os, Command->fe.freeDscriptors);
        }

        gcmkOS_SAFE_FREE(Command->os, Command);
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

gceSTATUS
gckASYNC_COMMAND_Commit(
    IN gckASYNC_COMMAND Command,
    IN gcoCMDBUF CommandBuffer,
    IN gcsQUEUE_PTR EventQueue
    )
{
    gceSTATUS       status;
    gctBOOL         available = gcvFALSE;
    gctBOOL         acquired = gcvFALSE;
    gcoCMDBUF       commandBufferObject = gcvNULL;
    struct _gcoCMDBUF _commandBufferObject;
    gctUINT8_PTR    commandBufferLogical;
    gctUINT8_PTR    commandBufferTail;
    gctUINT         commandBufferSize;
    gctUINT32       commandBufferAddress;
    gcsFEDescriptor descriptor;
    gctUINT32       skipFlushBytes;
    gctUINT32       fenceBytes;
    gctBOOL         needCopy;
    gctUINT32       oldValue;
    gctUINT32       flushBytes;

    gcmkHEADER();

    gckOS_QueryNeedCopy(Command->os, 0, &needCopy);

    gcmkVERIFY_OK(_HandlePatchList(Command, CommandBuffer, needCopy));

    /* Open user passed gcoCMDBUF object. */
    gcmkONERROR(gckKERNEL_OpenUserData(
        Command->kernel,
        needCopy,
        &_commandBufferObject,
        CommandBuffer,
        gcmSIZEOF(struct _gcoCMDBUF),
        (gctPOINTER *)&commandBufferObject
        ));

    gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);

    gckHARDWARE_FlushAsyncMMU(Command->hardware, gcvNULL, &flushBytes);

    gcmkONERROR(gckOS_AtomicExchange(Command->os,
                                     Command->hardware->pageTableDirty[gcvENGINE_BLT],
                                     0,
                                     &oldValue));

    if (oldValue)
    {
        commandBufferLogical
            = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
            +                commandBufferObject->startOffset;

        gckHARDWARE_FlushAsyncMMU(Command->hardware, commandBufferLogical, &flushBytes);

        skipFlushBytes = 0;
    }
    else
    {
        skipFlushBytes = flushBytes;
    }

    /* Compute the command buffer entry and the size. */
    commandBufferLogical
        = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
        +                commandBufferObject->startOffset
        +                skipFlushBytes;

    commandBufferSize
        = commandBufferObject->offset
        + Command->reservedTail
        - commandBufferObject->startOffset
        - skipFlushBytes;

    commandBufferTail
        = commandBufferLogical
        + commandBufferSize
        - Command->reservedTail;

    /* Get the hardware address. */
    if (Command->kernel && Command->kernel->virtualCommandBuffer)
    {
        gckKERNEL kernel = Command->kernel;
        gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer
            = gcmNAME_TO_PTR(commandBufferObject->physical);

        if (virtualCommandBuffer == gcvNULL)
        {
            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
        }

        gcmkONERROR(gckKERNEL_GetGPUAddress(
            Command->kernel,
            commandBufferLogical,
            gcvTRUE,
            virtualCommandBuffer,
            &commandBufferAddress
            ));
    }
    else
    {
        gcmkONERROR(gckHARDWARE_ConvertLogical(
            Command->hardware,
            commandBufferLogical,
            gcvTRUE,
            &commandBufferAddress
            ));
    }

    gcmkONERROR(gckHARDWARE_Fence(
        Command->hardware,
        gcvENGINE_BLT,
        commandBufferTail,
        Command->fence->address,
        Command->commitStamp,
        &fenceBytes
        ));

    descriptor.start = commandBufferAddress;
    descriptor.end   = commandBufferAddress + commandBufferSize;

    gcmkDUMPCOMMAND(
        Command->os,
        commandBufferLogical,
        commandBufferSize,
        gcvDUMP_BUFFER_USER,
        gcvFALSE
        );

    gckOS_AcquireMutex(Command->os, Command->mutex, gcvINFINITE);
    acquired = gcvTRUE;

    /* Acquire a slot. */
    for(;;)
    {
        gcmkONERROR(gckFE_ReserveSlot(Command->hardware, &Command->fe, &available));

        if (available)
        {
            break;
        }
        else
        {
            gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "No available slot, have to wait");

            gckOS_Delay(Command->os, 1);
        }
    }

    /* Send descriptor. */
    gckFE_Execute(Command->hardware, &Command->fe, &descriptor);

    Command->commitStamp++;

    gckOS_ReleaseMutex(Command->os, Command->mutex);
    acquired = gcvFALSE;

    gcmkVERIFY_OK(gckKERNEL_CloseUserData(
        Command->kernel,
        needCopy,
        gcvFALSE,
        CommandBuffer,
        gcmSIZEOF(struct _gcoCMDBUF),
        (gctPOINTER *)&commandBufferObject
        ));

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    if (acquired)
    {
        gckOS_ReleaseMutex(Command->os, Command->mutex);
    }

    if (commandBufferObject)
    {
        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
            Command->kernel,
            needCopy,
            gcvFALSE,
            CommandBuffer,
            gcmSIZEOF(struct _gcoCMDBUF),
            (gctPOINTER *)&commandBufferObject
            ));
    }

    gcmkFOOTER();
    return status;
}

gceSTATUS
gckASYNC_COMMAND_EnterCommit(
    IN gckASYNC_COMMAND Command
    )
{
    return gckOS_AcquireMutex(Command->os, Command->mutex, gcvINFINITE);
}


gceSTATUS
gckASYNC_COMMAND_ExitCommit(
    IN gckASYNC_COMMAND Command
    )
{
    return gckOS_ReleaseMutex(Command->os, Command->mutex);
}

gceSTATUS
gckASYNC_COMMAND_Execute(
    IN gckASYNC_COMMAND Command,
    IN gctUINT32 Start,
    IN gctUINT32 End
    )
{
    gceSTATUS status;
    gcsFEDescriptor descriptor;
    gctBOOL available;

    descriptor.start = Start;
    descriptor.end   = End;

    /* Acquire a slot. */
    for(;;)
    {
        gcmkONERROR(gckFE_ReserveSlot(Command->hardware, &Command->fe, &available));

        if (available)
        {
            break;
        }
        else
        {
            gckOS_Delay(Command->os, 1);
        }
    }

    /* Send descriptor. */
    gckFE_Execute(Command->hardware, &Command->fe, &descriptor);

    return gcvSTATUS_OK;

OnError:
    return status;
}

