/****************************************************************************
*
*    The MIT License (MIT)
*
*    Copyright (c) 2014 - 2020 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 - 2020 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_linux.h"
#include "gc_hal_kernel_allocator.h"
#include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/mman.h>
#include <linux/slab.h>
#include <linux/sched.h>

#define _GC_OBJ_ZONE    gcvZONE_DEVICE

#define DEBUG_FILE          "galcore_trace"
#define PARENT_FILE         "gpu"

#define gcdDEBUG_FS_WARN    "Experimental debug entry, may be removed in future release, do NOT rely on it!\n"

static gckGALDEVICE galDevice;

extern gcTA globalTA[16];

/******************************************************************************\
******************************** Debugfs Support *******************************
\******************************************************************************/

/******************************************************************************\
***************************** DEBUG SHOW FUNCTIONS *****************************
\******************************************************************************/

int gc_info_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    int i = 0;
    gceCHIPMODEL chipModel = 0;
    gctUINT32 chipRevision = 0;
    gctUINT32 productID = 0;
    gctUINT32 ecoID = 0;

    if (!device)
        return -ENXIO;

    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        if (device->kernels[i])
        {
            if (i == gcvCORE_VG)
            {
            }
            else
            {
                chipModel = device->kernels[i]->hardware->identity.chipModel;
                chipRevision = device->kernels[i]->hardware->identity.chipRevision;
                productID = device->kernels[i]->hardware->identity.productID;
                ecoID = device->kernels[i]->hardware->identity.ecoID;
            }

            seq_printf(m, "gpu      : %d\n", i);
            seq_printf(m, "model    : %4x\n", chipModel);
            seq_printf(m, "revision : %4x\n", chipRevision);
            seq_printf(m, "product  : %4x\n", productID);
            seq_printf(m, "eco      : %4x\n", ecoID);
            seq_printf(m, "\n");
        }
    }

    return 0;
}

int gc_clients_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;

    gckKERNEL kernel = _GetValidKernel(device);

    gcsDATABASE_PTR database;
    gctINT i, pid;
    char name[24];

    if (!kernel)
        return -ENXIO;

    seq_printf(m, "%-8s%s\n", "PID", "NAME");
    seq_printf(m, "------------------------\n");

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            pid = database->processID;

            gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));

            seq_printf(m, "%-8d%s\n", pid, name);
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    /* Success. */
    return 0;
}

int gc_meminfo_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);
    gckVIDMEM memory;
    gceSTATUS status;
    gcsDATABASE_PTR database;
    gctUINT32 i;

    gctUINT32 free = 0, used = 0, total = 0, minFree = 0, maxUsed = 0;

    gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
    gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};

    if (!kernel)
        return -ENXIO;

    status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);

    if (gcmIS_SUCCESS(status))
    {
        gcmkVERIFY_OK(
            gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));

        free    = memory->freeBytes;
        minFree = memory->minFreeBytes;
        used    = memory->bytes - memory->freeBytes;
        maxUsed = memory->bytes - memory->minFreeBytes;
        total   = memory->bytes;

        gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
    }

    seq_printf(m, "VIDEO MEMORY:\n");
    seq_printf(m, "  POOL SYSTEM:\n");
    seq_printf(m, "    Free :    %10u B\n", free);
    seq_printf(m, "    Used :    %10u B\n", used);
    seq_printf(m, "    MinFree : %10u B\n", minFree);
    seq_printf(m, "    MaxUsed : %10u B\n", maxUsed);
    seq_printf(m, "    Total :   %10u B\n", total);

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            gcsDATABASE_COUNTERS * counter;
            counter = &database->vidMemPool[gcvPOOL_VIRTUAL];
            virtualCounter.bytes += counter->bytes;
            virtualCounter.maxBytes += counter->maxBytes;

            counter = &database->nonPaged;
            nonPagedCounter.bytes += counter->bytes;
            nonPagedCounter.maxBytes += counter->maxBytes;
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    seq_printf(m, "  POOL VIRTUAL:\n");
    seq_printf(m, "    Used :    %10llu B\n", virtualCounter.bytes);
    seq_printf(m, "    MaxUsed : %10llu B\n", virtualCounter.maxBytes);

    return 0;
}

static const char * vidmemTypeStr[gcvVIDMEM_TYPE_COUNT] =
{
    "Generic",
    "Index",
    "Vertex",
    "Texture",
    "RenderTarget",
    "Depth",
    "Bitmap",
    "TileStatus",
    "Image",
    "Mask",
    "Scissor",
    "HZ",
    "ICache",
    "TxDesc",
    "Fence",
    "TFBHeader",
    "Command",
};

static const char * poolStr[gcvPOOL_NUMBER_OF_POOLS] =
{
    "Unknown",
    "Default",
    "Local",
    "Internal",
    "External",
    "Unified",
    "System",
    "Sram",
    "Virtual",
    "User",
    "Insram",
    "Exsram",
};

static void
_ShowDummyRecord(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database
    )
{
}

static void
_ShowVideoMemoryRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;
    gctUINT32 handle;
    gckVIDMEM_NODE nodeObject;
    gctPHYS_ADDR_T physical;
    gctINT32 refCount = 0;
    gctINT32 lockCount = 0;
    gceSTATUS status;

    seq_printf(m, "Video Memory Node:\n");
    seq_printf(m, "  handle         nodeObject       size         type     pool     physical  ref lock\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_VIDEO_MEMORY)
            {
                continue;
            }

            handle = gcmPTR2INT32(record->data);

            status = gckVIDMEM_HANDLE_Lookup2(
                record->kernel,
                Database,
                handle,
                &nodeObject
                );

            if (gcmIS_ERROR(status))
            {
                seq_printf(m, "%6u Invalid Node\n", handle);
                continue;
            }

            gcmkONERROR(gckVIDMEM_NODE_GetPhysical(record->kernel, nodeObject, 0, &physical));
            gcmkONERROR(gckVIDMEM_NODE_GetReference(record->kernel, nodeObject, &refCount));
            gcmkONERROR(gckVIDMEM_NODE_GetLockCount(record->kernel, nodeObject, &lockCount));

            seq_printf(m, "%#8x %#18lx %10lu %12s %8s %#12llx %4d %4d\n",
                handle,
                (unsigned long)nodeObject,
                (unsigned long)record->bytes,
                vidmemTypeStr[nodeObject->type],
                poolStr[nodeObject->pool],
                physical,
                refCount,
                lockCount
                );
        }
    }

OnError:
    return;
}

static void
_ShowCommandBufferRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    return;
}

static void
_ShowNonPagedRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "NonPaged Memory:\n");
    seq_printf(m, "  name              vaddr       size\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_NON_PAGED)
            {
                continue;
            }

            seq_printf(m, "%6u %#18lx %10lu\n",
                gcmPTR2INT32(record->physical),
                (unsigned long)record->data,
                (unsigned long)record->bytes
                );
        }
    }
}

static void
_ShowContiguousRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    return;
}

static void
_ShowSignalRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "User signal:\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_SIGNAL)
            {
                continue;
            }

            seq_printf(m, "%#10x\n", gcmPTR2INT32(record->data));
        }
    }
}

static void
_ShowLockRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;
    gceSTATUS status;
    gctUINT32 handle;
    gckVIDMEM_NODE nodeObject;

    seq_printf(m, "Video Memory Lock:\n");
    seq_printf(m, "  handle         nodeObject              vaddr\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_VIDEO_MEMORY_LOCKED)
            {
                continue;
            }

            handle = gcmPTR2INT32(record->data);

            status = gckVIDMEM_HANDLE_Lookup2(
                record->kernel,
                Database,
                handle,
                &nodeObject
                );

            if (gcmIS_ERROR(status))
            {
                nodeObject = gcvNULL;
            }

            seq_printf(m, "%#8x %#18lx %#18lx\n",
                handle,
                (unsigned long)nodeObject,
                (unsigned long)record->physical
                );
        }
    }
}

static void
_ShowContextRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "Context:\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_CONTEXT)
            {
                continue;
            }

            seq_printf(m, "%6u\n", gcmPTR2INT32(record->data));
        }
    }
}

static void
_ShowMapMemoryRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "Map Memory:\n");
    seq_printf(m, "  name              vaddr       size\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_MAP_MEMORY)
            {
                continue;
            }

            seq_printf(m, "%#6lx %#18lx %10lu\n",
                (unsigned long)record->physical,
                (unsigned long)record->data,
                (unsigned long)record->bytes
                );
        }
    }
}

static void
_ShowMapUserMemoryRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    return;
}

static void
_ShowShbufRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "ShBuf:\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_SHBUF)
            {
                continue;
            }

            seq_printf(m, "%#8x\n", gcmPTR2INT32(record->data));
        }
    }
}

static void
_ShowCounters(
    struct seq_file *File,
    gcsDATABASE_PTR Database
    )
{
    gctUINT i = 0;

    static const char * otherCounterNames[] = {
        "AllocNonPaged",
        "AllocContiguous",
        "MapUserMemory",
        "MapMemory",
    };

    gcsDATABASE_COUNTERS * otherCounters[] = {
        &Database->nonPaged,
        &Database->contiguous,
        &Database->mapUserMemory,
        &Database->mapMemory,
    };

    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");

    /* Print surface type counters. */
    seq_printf(File, "%-16s %16lld %16lld %16lld\n",
               "All-Types",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
    {
        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
                   vidmemTypeStr[i],
                   Database->vidMemType[i].bytes,
                   Database->vidMemType[i].maxBytes,
                   Database->vidMemType[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print surface pool counters. */
    seq_printf(File, "%-16s %16lld %16lld %16lld\n",
               "All-Pools",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
    {
        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
                   poolStr[i],
                   Database->vidMemPool[i].bytes,
                   Database->vidMemPool[i].maxBytes,
                   Database->vidMemPool[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print other counters. */
    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
    {
        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
                   otherCounterNames[i],
                   otherCounters[i]->bytes,
                   otherCounters[i]->maxBytes,
                   otherCounters[i]->totalBytes);
    }
    seq_puts(File, "\n");
}

static int
_ShowRecord(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database,
    IN gcsDATABASE_RECORD_PTR Record
    )
{
    gctUINT32 handle;
    gckVIDMEM_NODE nodeObject;
    gctPHYS_ADDR_T physical;
    gceSTATUS status = gcvSTATUS_OK;

    static const char * recordTypes[gcvDB_NUM_TYPES] = {
        "Unknown",
        "VideoMemory",
        "CommandBuffer",
        "NonPaged",
        "Contiguous",
        "Signal",
        "VidMemLock",
        "Context",
        "Idel",
        "MapMemory",
        "MapUserMemory",
        "ShBuf",
    };

    handle = gcmPTR2INT32(Record->data);

    if (Record->type == gcvDB_VIDEO_MEMORY || Record->type == gcvDB_VIDEO_MEMORY_LOCKED)
    {
        status = gckVIDMEM_HANDLE_Lookup2(
            Record->kernel,
            Database,
            handle,
            &nodeObject
        );

        if (gcmIS_ERROR(status))
        {
            seq_printf(File, "%6u Invalid Node\n", handle);
            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
        }
        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(Record->kernel, nodeObject, 0, &physical));
    }
    else
    {
        physical = (gctUINT64)(gctUINTPTR_T)Record->physical;
    }

    seq_printf(File, "%-14s %3d %16x %16zx %16zu\n",
        recordTypes[Record->type],
        Record->kernel->core,
        gcmPTR2INT32(Record->data),
        (size_t) physical,
        Record->bytes
        );

OnError:
    return status;
}

static void
_ShowDataBaseOldFormat(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database
    )
{
    gctINT pid;
    gctUINT i;
    char name[24];

    /* Process ID and name */
    pid = Database->processID;
    gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));

    seq_printf(File, "--------------------------------------------------------------------------------\n");
    seq_printf(File, "Process: %-8d %s\n", pid, name);

    seq_printf(File, "Records:\n");

    seq_printf(File, "%14s %3s %16s %16s %16s\n",
               "Type", "GPU", "Data/Node", "Physical/Node", "Bytes");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR record = Database->list[i];

        while (record != NULL)
        {
            _ShowRecord(File, Database, record);
            record = record->next;
        }
    }

    seq_printf(File, "Counters:\n");

    _ShowCounters(File, Database);
}

static void
_ShowDatabase(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database
    )
{
    gctINT pid;
    gctUINT i;
    char name[24];
    gctBOOL hasType[gcvDB_NUM_TYPES] = {0,};
    void (* showFuncs[])(struct seq_file *, gcsDATABASE_PTR) =
    {
        _ShowDummyRecord,
        _ShowVideoMemoryRecord,
        _ShowCommandBufferRecord,
        _ShowNonPagedRecord,
        _ShowContiguousRecord,
        _ShowSignalRecord,
        _ShowLockRecord,
        _ShowContextRecord,
        _ShowDummyRecord,
        _ShowMapMemoryRecord,
        _ShowMapUserMemoryRecord,
        _ShowShbufRecord,
    };

    gcmSTATIC_ASSERT(gcmCOUNTOF(showFuncs) == gcvDB_NUM_TYPES,
                     "DB type mismatch");

    /* Process ID and name */
    pid = Database->processID;
    gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));

    seq_printf(File, "--------------------------------------------------------------------------------\n");
    seq_printf(File, "Process: %-8d %s\n", pid, name);

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR record = Database->list[i];

        while (record != NULL)
        {
            hasType[record->type] = gcvTRUE;
            record = record->next;
        }
    }

    for (i = 0; i < gcvDB_NUM_TYPES; i++)
    {
        if (hasType[i])
        {
            showFuncs[i](File, Database);
        }
    }
}

static int
gc_db_show_old(struct seq_file *m, void *data)
{
    gcsDATABASE_PTR database;
    gctINT i;
    static gctUINT64 idleTime = 0;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    if (kernel->db->idleTime)
    {
        /* Record idle time if DB upated. */
        idleTime = kernel->db->idleTime;
        kernel->db->idleTime = 0;
    }

    /* Idle time since last call */
    seq_printf(m, "GPU Idle: %llu ns\n",  idleTime);

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            _ShowDataBaseOldFormat(m, database);
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    return 0 ;
}

static int
gc_db_show(struct seq_file *m, void *data)
{
    gcsDATABASE_PTR database;
    gctINT i;
    static gctUINT64 idleTime = 0;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    if (kernel->db->idleTime)
    {
        /* Record idle time if DB upated. */
        idleTime = kernel->db->idleTime;
        kernel->db->idleTime = 0;
    }

    /* Idle time since last call */
    seq_printf(m, "GPU Idle: %llu ns\n",  idleTime);

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            _ShowDatabase(m, database);
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    return 0 ;
}

static int
gc_version_show(struct seq_file *m, void *data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gcsPLATFORM * platform = gcvNULL;

    if (!device)
        return -ENXIO;

    platform = device->platform;
    if (!platform)
        return -ENXIO;

    seq_printf(m, "%s built at %s\n",  gcvVERSION_STRING, HOST);

    if (platform->name)
    {
        seq_printf(m, "Platform path: %s\n", platform->name);
    }
    else
    {
        seq_printf(m, "Code path: %s\n", __FILE__);
    }

    return 0 ;
}

static void print_ull(char dest[32], unsigned long long u)
{
    unsigned t[7];
    int i;

    if (u < 1000)
    {
        sprintf(dest, "%27llu", u);
        return;
    }

    for (i = 0; i < 7 && u; i++)
    {
        t[i] = do_div(u, 1000);
    }

    dest += sprintf(dest, "%*s", (7 - i) * 4, "");
    dest += sprintf(dest, "%3u", t[--i]);

    for (i--; i >= 0; i--)
    {
        dest += sprintf(dest, ",%03u", t[i]);
    }
}

/*******************************************************************************
**
** Show PM state timer.
**
** Entry is called as 'idle' for compatible reason, it shows more information
** than idle actually.
**
**  Start: Start time of this counting period.
**  End: End time of this counting peroid.
**  On: Time GPU stays in gcvPOWER_0N.
**  Off: Time GPU stays in gcvPOWER_0FF.
**  Idle: Time GPU stays in gcvPOWER_IDLE.
**  Suspend: Time GPU stays in gcvPOWER_SUSPEND.
*/
static int
gc_idle_show(struct seq_file *m, void *data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);
    char str[32];

    gctUINT64 on;
    gctUINT64 off;
    gctUINT64 idle;
    gctUINT64 suspend;

    if (!kernel)
        return -ENXIO;

    gckHARDWARE_QueryStateTimer(kernel->hardware, &on, &off, &idle, &suspend);

    /* Idle time since last call */
    print_ull(str, on);
    seq_printf(m, "On:      %s ns\n",  str);
    print_ull(str, off);
    seq_printf(m, "Off:     %s ns\n",  str);
    print_ull(str, idle);
    seq_printf(m, "Idle:    %s ns\n",  str);
    print_ull(str, suspend);
    seq_printf(m, "Suspend: %s ns\n",  str);

    return 0 ;
}

extern void
_DumpState(
    IN gckKERNEL Kernel
    );

/*******************************************************************************
**
** Show PM state timer.
**
** Entry is called as 'idle' for compatible reason, it shows more information
** than idle actually.
**
**  Start: Start time of this counting period.
**  End: End time of this counting peroid.
**  On: Time GPU stays in gcvPOWER_0N.
**  Off: Time GPU stays in gcvPOWER_0FF.
**  Idle: Time GPU stays in gcvPOWER_IDLE.
**  Suspend: Time GPU stays in gcvPOWER_SUSPEND.
*/

static int dumpCore = 0;

static int
gc_dump_trigger_show(struct seq_file *m, void *data)
{
#if gcdENABLE_3D
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = gcvNULL;

    if (dumpCore >= gcvCORE_MAJOR && dumpCore < gcvCORE_COUNT)
    {
        kernel = device->kernels[dumpCore];
    }

    if (!kernel)
        return -ENXIO;

#endif

    seq_printf(m, gcdDEBUG_FS_WARN);

#if gcdENABLE_3D
    seq_printf(m, "Get dump from /proc/kmsg or /sys/kernel/debug/gc/galcore_trace\n");

    if (kernel && kernel->hardware->options.powerManagement == gcvFALSE)
    {
        _DumpState(kernel);
    }
#endif

    return 0;
}

static int dumpProcess = 0;

static void
_ShowVideoMemoryOldFormat(
    struct seq_file *File,
    gcsDATABASE_PTR Database
    )
{
    gctUINT i = 0;

    static const char * otherCounterNames[] = {
        "AllocNonPaged",
        "AllocContiguous",
        "MapUserMemory",
        "MapMemory",
    };

    gcsDATABASE_COUNTERS * otherCounters[] = {
        &Database->nonPaged,
        &Database->contiguous,
        &Database->mapUserMemory,
        &Database->mapMemory,
    };

    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");

    /* Print surface type counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Types",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   vidmemTypeStr[i],
                   Database->vidMemType[i].bytes,
                   Database->vidMemType[i].maxBytes,
                   Database->vidMemType[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print surface pool counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Pools",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   poolStr[i],
                   Database->vidMemPool[i].bytes,
                   Database->vidMemPool[i].maxBytes,
                   Database->vidMemPool[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print other counters. */
    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   otherCounterNames[i],
                   otherCounters[i]->bytes,
                   otherCounters[i]->maxBytes,
                   otherCounters[i]->totalBytes);
    }
    seq_puts(File, "\n");
}

static void
_ShowVideoMemory(
    struct seq_file *File,
    gcsDATABASE_PTR Database
    )
{
    gctUINT i = 0;

    static const char * otherCounterNames[] = {
        "AllocNonPaged",
        "MapMemory",
    };

    gcsDATABASE_COUNTERS * otherCounters[] = {
        &Database->nonPaged,
        &Database->mapMemory,
    };

    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");

    /* Print surface type counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Types",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   vidmemTypeStr[i],
                   Database->vidMemType[i].bytes,
                   Database->vidMemType[i].maxBytes,
                   Database->vidMemType[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print surface pool counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Pools",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   poolStr[i],
                   Database->vidMemPool[i].bytes,
                   Database->vidMemPool[i].maxBytes,
                   Database->vidMemPool[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print other counters. */
    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   otherCounterNames[i],
                   otherCounters[i]->bytes,
                   otherCounters[i]->maxBytes,
                   otherCounters[i]->totalBytes);
    }
    seq_puts(File, "\n");
}

static int gc_vidmem_show_old(struct seq_file *m, void *unused)
{
    gceSTATUS status;
    gcsDATABASE_PTR database;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    char name[64];
    int i;

    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    if (dumpProcess == 0)
    {
        /* Acquire the database mutex. */
        gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

        for (i = 0; i < gcmCOUNTOF(kernel->db->db); i++)
        {
            for (database = kernel->db->db[i];
                 database != gcvNULL;
                 database = database->next)
            {
                gckOS_GetProcessNameByPid(database->processID, gcmSIZEOF(name), name);
                seq_printf(m, "VidMem Usage (Process %u: %s):\n", database->processID, name);
                _ShowVideoMemoryOldFormat(m, database);
                seq_puts(m, "\n");
            }
        }

        /* Release the database mutex. */
        gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
    }
    else
    {
        /* Find the database. */
        status = gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database);

        if (gcmIS_ERROR(status))
        {
            seq_printf(m, "ERROR: process %d not found\n", dumpProcess);
            return 0;
        }

        gckOS_GetProcessNameByPid(dumpProcess, gcmSIZEOF(name), name);
        seq_printf(m, "VidMem Usage (Process %d: %s):\n", dumpProcess, name);
        _ShowVideoMemoryOldFormat(m, database);
    }

    return 0;
}

static int gc_vidmem_show(struct seq_file *m, void *unused)
{
    gceSTATUS status;
    gcsDATABASE_PTR database;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    char name[64];
    int i;

    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    if (dumpProcess == 0)
    {
        /* Acquire the database mutex. */
        gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

        for (i = 0; i < gcmCOUNTOF(kernel->db->db); i++)
        {
            for (database = kernel->db->db[i];
                 database != gcvNULL;
                 database = database->next)
            {
                gckOS_GetProcessNameByPid(database->processID, gcmSIZEOF(name), name);
                seq_printf(m, "VidMem Usage (Process %u: %s):\n", database->processID, name);
                _ShowVideoMemory(m, database);
                seq_puts(m, "\n");
            }
        }

        /* Release the database mutex. */
        gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
    }
    else
    {
        /* Find the database. */
        status = gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database);

        if (gcmIS_ERROR(status))
        {
            seq_printf(m, "ERROR: process %d not found\n", dumpProcess);
            return 0;
        }

        gckOS_GetProcessNameByPid(dumpProcess, gcmSIZEOF(name), name);
        seq_printf(m, "VidMem Usage (Process %d: %s):\n", dumpProcess, name);
        _ShowVideoMemory(m, database);
    }

    return 0;
}

static inline int strtoint_from_user(const char __user *s,
                        size_t count, int *res)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
    int ret = kstrtoint_from_user(s, count, 10, res);

    return ret < 0 ? ret : count;
#else
    /* sign, base 2 representation, newline, terminator */
    char buf[1 + sizeof(long) * 8 + 1 + 1];

    size_t len = min(count, sizeof(buf) - 1);

    if (copy_from_user(buf, s, len))
        return -EFAULT;
    buf[len] = '\0';

    *res = (int) simple_strtol(buf, NULL, 0);

    return count;
#endif
}

static int gc_vidmem_write(const char __user *buf, size_t count, void* data)
{
    return strtoint_from_user(buf, count, &dumpProcess);
}

static int gc_dump_trigger_write(const char __user *buf, size_t count, void* data)
{
    return strtoint_from_user(buf, count, &dumpCore);
}

static int gc_clk_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gctUINT i;
    gceSTATUS status;

    if (!device)
        return -ENXIO;

    for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
    {
        if (device->kernels[i])
        {
            gckHARDWARE hardware = device->kernels[i]->hardware;

            if (i == gcvCORE_VG)
            {
                continue;
            }

            status = gckHARDWARE_QueryFrequency(hardware);
            if (gcmIS_ERROR(status))
            {
                seq_printf(m, "query gpu%d clock fail.\n", i);
                continue;
            }

            if (hardware->mcClk)
            {
                seq_printf(m, "gpu%d mc clock: %d HZ.\n", i, hardware->mcClk);
            }

            if (hardware->shClk)
            {
                seq_printf(m, "gpu%d sh clock: %d HZ.\n", i, hardware->shClk);
            }
        }
    }

    return 0;
}

static gcsINFO InfoList[] =
{
    {"info", gc_info_show},
    {"clients", gc_clients_show},
    {"meminfo", gc_meminfo_show},
    {"idle", gc_idle_show},
    {"database", gc_db_show_old},
    {"database64x", gc_db_show},
    {"version", gc_version_show},
    {"vidmem", gc_vidmem_show_old, gc_vidmem_write},
    {"vidmem64x", gc_vidmem_show, gc_vidmem_write},
    {"dump_trigger", gc_dump_trigger_show, gc_dump_trigger_write},
    {"clk", gc_clk_show},
};

static gceSTATUS
_DebugfsInit(
    IN gckGALDEVICE Device
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gckDEBUGFS_DIR dir = &Device->debugfsDir;

    gcmkONERROR(gckDEBUGFS_DIR_Init(dir, gcvNULL, "gc"));
    gcmkONERROR(gckDEBUGFS_DIR_CreateFiles(dir, InfoList, gcmCOUNTOF(InfoList), Device));

OnError:
    return status;
}

static void
_DebugfsCleanup(
    IN gckGALDEVICE Device
    )
{
    gckDEBUGFS_DIR dir = &Device->debugfsDir;

    if (Device->debugfsDir.root)
    {
        gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(dir, InfoList, gcmCOUNTOF(InfoList)));

        gckDEBUGFS_DIR_Deinit(dir);
    }
}


/******************************************************************************\
*************************** Memory Allocation Wrappers *************************
\******************************************************************************/

static gceSTATUS
_AllocateMemory(
    IN gckGALDEVICE Device,
    IN gctSIZE_T Bytes,
    OUT gctPOINTER *Logical,
    OUT gctPHYS_ADDR *Physical,
    OUT gctUINT64 *PhysAddr
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gctPHYS_ADDR_T physAddr;

    gcmkHEADER_ARG("Device=%p Bytes=0x%zx", Device, Bytes);

    gcmkVERIFY_ARGUMENT(Device != NULL);
    gcmkVERIFY_ARGUMENT(Logical != NULL);
    gcmkVERIFY_ARGUMENT(Physical != NULL);
    gcmkVERIFY_ARGUMENT(PhysAddr != NULL);

    gcmkONERROR(gckOS_AllocateNonPagedMemory(
        Device->os, gcvFALSE, gcvALLOC_FLAG_CONTIGUOUS, &Bytes, Physical, Logical
        ));

    gcmkONERROR(gckOS_GetPhysicalFromHandle(
        Device->os, *Physical, 0, &physAddr
        ));

    *PhysAddr = physAddr;

OnError:
    gcmkFOOTER_ARG(
        "*Logical=%p *Physical=%p *PhysAddr=0x%llx",
        gcmOPT_POINTER(Logical), gcmOPT_POINTER(Physical), gcmOPT_VALUE(PhysAddr)
        );

    return status;
}

static gceSTATUS
_FreeMemory(
    IN gckGALDEVICE Device,
    IN gctPOINTER Logical,
    IN gctPHYS_ADDR Physical
    )
{
    gceSTATUS status;

    gcmkHEADER_ARG("Device=%p Logical=%p Physical=%p",
                   Device, Logical, Physical);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    status = gckOS_FreeNonPagedMemory(
        Device->os, Physical, Logical,
        ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
        );

    gcmkFOOTER();
    return status;
}

static gceSTATUS
_SetupContiguousVidMem(
    IN gckGALDEVICE Device,
    IN const gcsMODULE_PARAMETERS * Args
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gctUINT64 physAddr = ~0ULL;
    gckGALDEVICE device = Device;

    gcmkHEADER_ARG("Device=%p Args=%p", Device, Args);

    /* set up the contiguous memory */
    device->contiguousBase = Args->contiguousBase;
    device->contiguousSize = Args->contiguousSize;

    if (Args->contiguousSize == 0)
    {
        gcmkFOOTER_NO();
        return gcvSTATUS_OK;
    }

    if (Args->contiguousBase == 0)
    {
        while (device->contiguousSize > 0)
        {
            /* Allocate contiguous memory. */
            status = _AllocateMemory(
                device,
                device->contiguousSize,
                &device->contiguousLogical,
                &device->contiguousPhysical,
                &physAddr
                );

            if (gcmIS_SUCCESS(status))
            {
                status = gckVIDMEM_Construct(
                    device->os,
                    physAddr,
                    device->contiguousSize,
                    64,
                    Args->bankSize,
                    &device->contiguousVidMem
                    );

                if (gcmIS_SUCCESS(status))
                {
                    gckALLOCATOR allocator = ((PLINUX_MDL)device->contiguousPhysical)->allocator;
                    device->contiguousVidMem->capability = allocator->capability | gcvALLOC_FLAG_MEMLIMIT;
                    device->contiguousVidMem->physical = device->contiguousPhysical;
                    device->contiguousBase = physAddr;
                    if (device->contiguousBase > 0xFFFFFFFFULL)
                    {
                        device->contiguousVidMem->capability &= ~gcvALLOC_FLAG_4GB_ADDR;
                    }
                    break;
                }

                gcmkONERROR(_FreeMemory(
                    device,
                    device->contiguousLogical,
                    device->contiguousPhysical
                    ));

                device->contiguousLogical  = gcvNULL;
                device->contiguousPhysical = gcvNULL;
            }

            if (device->contiguousSize <= (4 << 20))
            {
                device->contiguousSize = 0;
            }
            else
            {
                device->contiguousSize -= (4 << 20);
            }
        }
    }
    else
    {
        /* Create the contiguous memory heap. */
        status = gckVIDMEM_Construct(
            device->os,
            Args->contiguousBase,
            Args->contiguousSize,
            64,
            Args->bankSize,
            &device->contiguousVidMem
            );

        if (gcmIS_ERROR(status))
        {
            /* Error, disable contiguous memory pool. */
            device->contiguousVidMem = gcvNULL;
            device->contiguousSize   = 0;
        }
        else
        {
            gckALLOCATOR allocator;
            gctBOOL contiguousRequested = Args->contiguousRequested;

#if gcdCAPTURE_ONLY_MODE
            contiguousRequested = gcvTRUE;
#endif

            gcmkONERROR(gckOS_RequestReservedMemory(
                device->os, Args->contiguousBase, Args->contiguousSize,
                "galcore contiguous memory",
                contiguousRequested,
                &device->contiguousPhysical
                ));

            allocator = ((PLINUX_MDL)device->contiguousPhysical)->allocator;

            device->contiguousVidMem->capability = allocator->capability | gcvALLOC_FLAG_MEMLIMIT;
            device->contiguousVidMem->physical = device->contiguousPhysical;
            device->requestedContiguousBase = Args->contiguousBase;
            device->requestedContiguousSize = Args->contiguousSize;

            device->contiguousPhysName = 0;
            device->contiguousSize = Args->contiguousSize;
        }
    }

    if (Args->showArgs)
    {
        gcmkPRINT("Galcore Info: ContiguousBase=0x%llx ContiguousSize=0x%zx\n", device->contiguousBase, device->contiguousSize);
    }

OnError:
    gcmkFOOTER();
    return status;
}

static gceSTATUS
_SetupExternalSRAMVidMem(
    IN gckGALDEVICE Device
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gckGALDEVICE device = Device;
    gctINT32 i, j = 0;

    gcmkHEADER_ARG("Device=%p", Device);

    /* Setup external SRAM memory region. */
    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
    {
        if (!device->extSRAMSizes[i])
        {
            /* Keep this path for internal test, read from feature database. */
            device->extSRAMSizes[i] = device->device->extSRAMSizes[i];
        }

        if (device->extSRAMSizes[i] > 0)
        {
            /* create the external SRAM memory heap */
            status = gckVIDMEM_Construct(
                device->os,
                device->extSRAMBases[i],
                device->extSRAMSizes[i],
                64,
                0,
                &device->extSRAMVidMem[i]
                );

            if (gcmIS_ERROR(status))
            {
                /* Error, disable external SRAM heap. */
                device->extSRAMSizes[i] = 0;
            }
            else
            {
                char sRAMName[40];
                snprintf(sRAMName, gcmSIZEOF(sRAMName) - 1, "Galcore external sram%d", i);

#if gcdCAPTURE_ONLY_MODE
                device->args.sRAMRequested = gcvTRUE;
#endif
                /* Map external SRAM memory. */
                gcmkONERROR(gckOS_RequestReservedMemory(
                        device->os,
                        device->extSRAMBases[i], device->extSRAMSizes[i],
                        sRAMName,
                        device->args.sRAMRequested,
                        &device->extSRAMPhysical[i]
                        ));

                device->extSRAMVidMem[i]->physical = device->extSRAMPhysical[i];
                device->device->extSRAMPhysical[i] = device->extSRAMPhysical[i];

                for (j = 0; j < gcdMAX_GPU_COUNT; j++)
                {
                    if (device->irqLines[j] != -1 && device->kernels[j])
                    {
                        device->kernels[j]->hardware->options.extSRAMGPUPhysNames[i] = gckKERNEL_AllocateNameFromPointer(device->kernels[j], device->extSRAMPhysical[i]);
                    }
                }
            }
        }
    }

OnError:
    gcmkFOOTER();
    return status;
}

/******************************************************************************\
******************************* Interrupt Handler ******************************
\******************************************************************************/
static irqreturn_t isrRoutine(int irq, void *ctxt)
{
    gceSTATUS status;
    gckGALDEVICE device;
    gceCORE core = (gceCORE)gcmPTR2INT32(ctxt) - 1;

    device = galDevice;

    /* Call kernel interrupt notification. */
    status = gckHARDWARE_Interrupt(device->kernels[core]->hardware);

    if (gcmIS_SUCCESS(status))
    {
        up(&device->semas[core]);
        return IRQ_HANDLED;
    }

    return IRQ_NONE;
}

static irqreturn_t isrRoutineVG(int irq, void *ctxt)
{
    return IRQ_NONE;
}

static const char *isrNames[] =
{
    "galcore:0",
    "galcore:3d-1",
    "galcore:3d-2",
    "galcore:3d-3",
    "galcore:3d-4",
    "galcore:3d-5",
    "galcore:3d-6",
    "galcore:3d-7",
    "galcore:2d",
    "galcore:vg",
#if gcdDEC_ENABLE_AHB
    "galcore:dec"
#endif
};

static int isrRoutinePoll(void *ctxt)
{
    gckGALDEVICE device;
    gceCORE core = (gceCORE)gcmPTR2INT32(ctxt);

    device = galDevice;

    gcmSTATIC_ASSERT(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
                     "isrNames array does not match core types");

    while (1)
    {
        if (unlikely(device->killThread))
        {
            /* The daemon exits. */
            while (!kthread_should_stop())
            {
                gckOS_Delay(device->os, 1);
            }

            return 0;
        }

        if (core == gcvCORE_VG)
        {
            isrRoutineVG(-1, gcvNULL);
        }
        else
        {
            isrRoutine(-1, (gctPOINTER)(uintptr_t)(core + 1));
        }

        gckOS_Delay(device->os, 10);
    }

    return 0;
}

static gceSTATUS
_SetupIsr(
    IN gceCORE Core
    )
{
    gctINT ret = 0;
    gceSTATUS status = gcvSTATUS_OK;
    gckGALDEVICE Device = galDevice;
    irq_handler_t handler;

    gcmkHEADER_ARG("Device=%p Core=%d", Device, Core);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    gcmSTATIC_ASSERT(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
                     "isrNames array does not match core types");

    if (Device->irqLines[Core] == -1)
    {
        gctUINT64 isrPolling = -1;

        if (Device->isrThread[Core])
        {
            return status;
        }

        gckOS_QueryOption(Device->os, "isrPoll", &isrPolling);

        /* use kthread to poll int stat */
        if (gcmBITTEST(isrPolling, Core) != 0)
        {
            struct task_struct * task;

            Device->killIsrThread = gcvFALSE;

            task = kthread_run(isrRoutinePoll, (gctPOINTER)Core, "%s_poll", isrNames[Core]);

            if (IS_ERR(task))
            {
                gcmkTRACE_ZONE(
                    gcvLEVEL_ERROR, gcvZONE_DRIVER,
                    "%s(%d): Could not start the intr poll thread.\n",
                    __FUNCTION__, __LINE__
                    );

                gcmkONERROR(gcvSTATUS_GENERIC_IO);
            }

            gcmkPRINT("galcore: polling core%d int state\n", Core);

            Device->isrThread[Core] = task;
            Device->isrInitializeds[Core] = gcvTRUE;

            return status;
        }
        /* it should not run to here */
        return gcvSTATUS_INVALID_ARGUMENT;
    }

    handler = (Core == gcvCORE_VG) ? isrRoutineVG : isrRoutine;

    /*
     * Hook up the isr based on the irq line.
     * For shared irq, device-id can not be 0, but CORE_MAJOR value is.
     * Add by 1 here and subtract by 1 in isr to fix the issue.
     */
    ret = request_irq(
        Device->irqLines[Core], handler, gcdIRQF_FLAG,
        isrNames[Core], (void *)(uintptr_t)(Core + 1)
        );

    if (ret != 0)
    {
        gcmkTRACE_ZONE(
            gcvLEVEL_ERROR, gcvZONE_DRIVER,
            "%s(%d): Could not register irq line %d (error=%d)\n",
            __FUNCTION__, __LINE__,
            Device->irqLines[Core], ret
            );

        gcmkONERROR(gcvSTATUS_GENERIC_IO);
    }

    /* Mark ISR as initialized. */
    Device->isrInitializeds[Core] = gcvTRUE;

OnError:
    gcmkFOOTER();
    return status;
}

static gceSTATUS
_ReleaseIsr(
    IN gceCORE Core
    )
{
    gckGALDEVICE Device = galDevice;

    gcmkHEADER_ARG("Device=%p Core=%d", Device, Core);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    /* release the irq */
    if (Device->isrInitializeds[Core])
    {
        if (Device->isrThread[Core])
        {
            Device->killIsrThread = gcvTRUE;
            kthread_stop(Device->isrThread[Core]);
            Device->isrThread[Core] = gcvNULL;
        }
        else
        {
            free_irq(Device->irqLines[Core], (void *)(uintptr_t)(Core + 1));
        }

        Device->isrInitializeds[Core] = gcvFALSE;
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

static int threadRoutine(void *ctxt)
{
    gckGALDEVICE device = galDevice;
    gceCORE core = (gceCORE) gcmPTR2INT32(ctxt);

    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
                   "Starting isr Thread with extension=%p",
                   device);


    for (;;)
    {
        int down;

        down = down_interruptible(&device->semas[core]);
        if (down && down != -EINTR)
        {
            return down;
        }

        if (unlikely(device->killThread))
        {
            /* The daemon exits. */
            while (!kthread_should_stop())
            {
                gckOS_Delay(device->os, 1);
            }

            return 0;
        }

        gckKERNEL_Notify(device->kernels[core], gcvNOTIFY_INTERRUPT);
    }
}

static gceSTATUS
_StartThread(
    IN gckGALDEVICE Device,
    IN gceCORE Core
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gckGALDEVICE device = galDevice;
    struct task_struct * task;

    if (device->kernels[Core] != gcvNULL)
    {
        /* Start the kernel thread. */
        task = kthread_run(threadRoutine, (void *)Core,
                "galcore_deamon/%d", Core);

        if (IS_ERR(task))
        {
            gcmkTRACE_ZONE(
                gcvLEVEL_ERROR, gcvZONE_DRIVER,
                "%s(%d): Could not start the kernel thread.\n",
                __FUNCTION__, __LINE__
                );

            gcmkONERROR(gcvSTATUS_GENERIC_IO);
        }

        device->threadCtxts[Core]         = task;
        device->threadInitializeds[Core] = device->kernels[Core]->threadInitialized = gcvTRUE;

        /* Set highest non RT priority, same as work queues. */
        set_user_nice(task, MIN_NICE);
    }
    else
    {
        device->threadInitializeds[Core] = gcvFALSE;
    }

OnError:
    return status;
}

static void
_StopThread(
    gckGALDEVICE Device,
    gceCORE Core
    )
{
    if (Device->threadInitializeds[Core])
    {
        Device->killThread = gcvTRUE;
        up(&Device->semas[Core]);

        kthread_stop(Device->threadCtxts[Core]);
        Device->threadCtxts[Core]        = gcvNULL;
        Device->threadInitializeds[Core] = gcvFALSE;
    }
}

/*******************************************************************************
**
**  gckGALDEVICE_Construct
**
**  Constructor.
**
**  INPUT:
**
**  OUTPUT:
**
**      gckGALDEVICE * Device
**          Pointer to a variable receiving the gckGALDEVICE object pointer on
**          success.
*/
gceSTATUS
gckGALDEVICE_Construct(
    IN gcsPLATFORM * Platform,
    IN const gcsMODULE_PARAMETERS * Args,
    OUT gckGALDEVICE *Device
    )
{
    gckKERNEL kernel = gcvNULL;
    gckGALDEVICE device;
    gctINT32 i;

#if !gcdCAPTURE_ONLY_MODE
    gceHARDWARE_TYPE type;
#endif

    gceSTATUS status = gcvSTATUS_OK;
    gctUINT64 isrPolling = -1;

    gcmkHEADER_ARG("Platform=%p Args=%p", Platform, Args);

    /* Allocate device structure. */
    device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN);

    if (!device)
    {
        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
    }

    memset(device, 0, sizeof(struct _gckGALDEVICE));

    device->platform = Platform;
    device->platform->dev = gcvNULL;

    device->args = *Args;

    /* Clear irq lines. */
    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        device->irqLines[i] = -1;
#if USE_LINUX_PCIE
        device->bars[i] = -1;
#endif
    }

    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        device->irqLines[i]                  = Args->irqs[i];
        device->requestedRegisterMemBases[i] = Args->registerBases[i];
        device->requestedRegisterMemSizes[i] = Args->registerSizes[i];
#if USE_LINUX_PCIE
        device->bars[i]                      = Args->bars[i];
#endif
        gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE,
                       "Get register base %llx of core %d",
                       Args->registerBases[i], i);
    }

    device->requestedContiguousBase  = 0;
    device->requestedContiguousSize  = 0;

    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        unsigned long physical;
        physical = (unsigned long)device->requestedRegisterMemBases[i];

        /* Set up register memory region. */
        if (physical != 0)
        {
            if (Args->registerBasesMapped[i])
            {
                device->registerBases[i] = Args->registerBasesMapped[i];
                device->requestedRegisterMemBases[i] = 0;
            }
            else
            {
#if USE_LINUX_PCIE
                gcmkPRINT("register should be mapped in platform layer");
#endif
                if (!request_mem_region(physical,
                        device->requestedRegisterMemSizes[i],
                        "galcore register region"))
                {
                    gcmkTRACE_ZONE(
                            gcvLEVEL_ERROR, gcvZONE_DRIVER,
                            "%s(%d): Failed to claim %lu bytes @ 0x%llx\n",
                            __FUNCTION__, __LINE__,
                            device->requestedRegisterMemSizes[i], physical
                            );

                    gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0) && (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
                device->registerBases[i] = (gctPOINTER)ioremap(
#else
                device->registerBases[i] = (gctPOINTER)ioremap_nocache(
#endif
                        physical, device->requestedRegisterMemSizes[i]);

                if (device->registerBases[i] == gcvNULL)
                {
                    gcmkTRACE_ZONE(
                            gcvLEVEL_ERROR, gcvZONE_DRIVER,
                            "%s(%d): Unable to map %ld bytes @ 0x%zx\n",
                            __FUNCTION__, __LINE__,
                            physical, device->requestedRegisterMemSizes[i]
                            );

                    gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                }
            }
        }
    }

    /* Set the base address */
    device->baseAddress = device->physBase = Args->baseAddress;
    device->physSize = Args->physSize;

    /* Set the external base address */
    device->externalBase = Args->externalBase;
    device->externalSize = Args->externalSize;

    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
    {
        device->extSRAMBases[i] = Args->extSRAMBases[i];
        device->extSRAMSizes[i] = Args->extSRAMSizes[i];
    }

    /* Ensure root debugfs dir is created before allocator init. */
    gcmkONERROR(_DebugfsInit(device));

    /* Construct the gckOS object. */
    gcmkONERROR(gckOS_Construct(device, &device->os));


    if (device->externalSize > 0)
    {
        /* create the external memory heap */
        status = gckVIDMEM_Construct(
            device->os,
            device->externalBase,
            device->externalSize,
            64,
            0,
            &device->externalVidMem
            );

        if (gcmIS_ERROR(status))
        {
            /* Error, disable external heap. */
            device->externalSize = 0;
        }
        else
        {
            /* Map external memory. */
            gcmkONERROR(gckOS_RequestReservedMemory(
                    device->os,
                    device->externalBase, device->externalSize,
                    "galcore external memory",
                    gcvTRUE,
                    &device->externalPhysical
                    ));

            device->externalVidMem->physical = device->externalPhysical;
        }
    }

    /* Construct the gckDEVICE object for os independent core management. */
    gcmkONERROR(gckDEVICE_Construct(device->os, &device->device));

    device->device->showSRAMMapInfo = Args->showArgs;

    device->platform->dev = device->device;

    gckOS_QueryOption(device->os, "isrPoll", &isrPolling);

    if (device->irqLines[gcvCORE_MAJOR] != -1 || gcmBITTEST(isrPolling, gcvCORE_MAJOR)!= 0)
    {
        gcmkONERROR(gctaOS_ConstructOS(device->os, &device->taos));
    }

    /* Setup contiguous video memory pool. */
    gcmkONERROR(_SetupContiguousVidMem(device, Args));

#if gcdEXTERNAL_SRAM_DEFAULT_POOL
    /* Setup external SRAM video memory pool. */
    gcmkONERROR(_SetupExternalSRAMVidMem(device));
#endif

    /* Add core for all available major cores. */
    for (i = gcvCORE_MAJOR; i <= gcvCORE_3D_MAX; i++)
    {
        if (device->irqLines[i] != -1 || gcmBITTEST(isrPolling, i)!= 0)
        {
            gcmkONERROR(gcTA_Construct(
                device->taos,
                (gceCORE)i,
                &globalTA[i]
                ));

            gcmkONERROR(gckDEVICE_AddCore(
                device->device,
                (gceCORE)i,
                Args->chipIDs[i],
                device,
                &device->kernels[i]
                ));

            gcmkONERROR(gckHARDWARE_SetFastClear(
                device->kernels[i]->hardware,
                Args->fastClear,
                Args->compression
                ));

            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                device->kernels[i]->hardware,
                Args->powerManagement
                ));

#if gcdENABLE_FSCALE_VAL_ADJUST
            gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
                device->kernels[i]->hardware,
                Args->gpu3DMinClock
                ));
#endif

            gcmkONERROR(gckHARDWARE_SetGpuProfiler(
                device->kernels[i]->hardware,
                Args->gpuProfiler
                ));
        }
        else
        {
            device->kernels[i] = gcvNULL;
        }
    }

#if !gcdCAPTURE_ONLY_MODE
    if (device->irqLines[gcvCORE_2D] != -1 || gcmBITTEST(isrPolling, gcvCORE_2D)!= 0)
    {
        gcmkONERROR(gckDEVICE_AddCore(
            device->device,
            gcvCORE_2D,
            gcvCHIP_ID_DEFAULT,
            device,
            &device->kernels[gcvCORE_2D]
            ));

        /* Verify the hardware type */
        gcmkONERROR(gckHARDWARE_GetType(
            device->kernels[gcvCORE_2D]->hardware,
            &type
            ));

        if (type != gcvHARDWARE_2D)
        {
            gcmkTRACE_ZONE(
                gcvLEVEL_ERROR, gcvZONE_DRIVER,
                "%s(%d): Unexpected hardware type: %d\n",
                __FUNCTION__, __LINE__,
                type
                );

            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
        }

        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
            device->kernels[gcvCORE_2D]->hardware,
            Args->powerManagement
            ));

#if gcdENABLE_FSCALE_VAL_ADJUST
        gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
            device->kernels[gcvCORE_2D]->hardware, 1
            ));
#endif
    }
    else
    {
        device->kernels[gcvCORE_2D] = gcvNULL;
    }

    if (device->irqLines[gcvCORE_VG] != -1 || gcmBITTEST(isrPolling, gcvCORE_VG)!= 0)
    {
    }
    else
    {
        device->kernels[gcvCORE_VG] = gcvNULL;
    }
#else
    device->kernels[gcvCORE_2D] = gcvNULL;

    device->kernels[gcvCORE_VG] = gcvNULL;
#endif

#if !gcdEXTERNAL_SRAM_DEFAULT_POOL
    /* Setup external SRAM video memory pool. */
    gcmkONERROR(_SetupExternalSRAMVidMem(device));
#endif

    /* Initialize the kernel thread semaphores. */
    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        if ((device->irqLines[i] != -1 || gcmBITTEST(isrPolling, i)!= 0)
            && device->kernels[i])
        {
            sema_init(&device->semas[i], 0);
        }
    }

    /* Grab the first valid kernel. */
    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        if (device->kernels[i] != gcvNULL)
        {
            kernel = device->kernels[i];
            break;
        }
    }

    if (!kernel)
    {
        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
    }

    if (device->internalPhysical)
    {
        device->internalPhysName = gcmPTR_TO_NAME(device->internalPhysical);
    }

    if (device->externalPhysical)
    {
        device->externalPhysName = gcmPTR_TO_NAME(device->externalPhysical);
    }

    if (device->contiguousPhysical)
    {
        device->contiguousPhysName = gcmPTR_TO_NAME(device->contiguousPhysical);
    }

    /* Return pointer to the device. */
    *Device = galDevice = device;

OnError:
    if (gcmIS_ERROR(status))
    {
        /* Roll back. */
        gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
    }

    gcmkFOOTER();
    return status;
}

/*******************************************************************************
**
**  gckGALDEVICE_Destroy
**
**  Class destructor.
**
**  INPUT:
**
**      Nothing.
**
**  OUTPUT:
**
**      Nothing.
**
**  RETURNS:
**
**      Nothing.
*/
gceSTATUS
gckGALDEVICE_Destroy(
    gckGALDEVICE Device)
{
    gctINT i, j = 0;
    gckKERNEL kernel = gcvNULL;

    gcmkHEADER_ARG("Device=%p", Device);

    if (Device != gcvNULL)
    {
        /* Grab the first available kernel */
        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
        {
            if (Device->kernels[i])
            {
                kernel = Device->kernels[i];
                break;
            }
        }

        if (kernel)
        {
            if (Device->internalPhysName != 0)
            {
                gcmRELEASE_NAME(Device->internalPhysName);
                Device->internalPhysName = 0;
            }
            if (Device->externalPhysName != 0)
            {
                gcmRELEASE_NAME(Device->externalPhysName);
                Device->externalPhysName = 0;
            }
            if (Device->contiguousPhysName != 0)
            {
                gcmRELEASE_NAME(Device->contiguousPhysName);
                Device->contiguousPhysName = 0;
            }
        }

        /* Destroy per-core SRAM heap. */
        for (i = 0; i < gcvCORE_COUNT; i++)
        {
            if (Device->kernels[i])
            {
                kernel = Device->kernels[i];

                for (j = gcvSRAM_INTERNAL0; j < gcvSRAM_INTER_COUNT; j++)
                {
                    if (kernel->sRAMPhysical[j] != gcvNULL)
                    {
                        /* Release reserved SRAM memory. */
                        gckOS_ReleaseReservedMemory(
                            Device->os,
                            kernel->sRAMPhysical[j]
                            );

                        kernel->sRAMPhysical[j] = gcvNULL;
                    }

                    if (kernel->sRAMVidMem[j] != gcvNULL)
                    {
                        /* Destroy the SRAM contiguous heap. */
                        gcmkVERIFY_OK(gckVIDMEM_Destroy(kernel->sRAMVidMem[j]));
                        kernel->sRAMVidMem[j] = gcvNULL;
                    }
                }
            }
        }

        if (Device->device)
        {
            gcmkVERIFY_OK(gckDEVICE_Destroy(Device->os, Device->device));

            for (i = 0; i < gcdMAX_GPU_COUNT; i++)
            {
                if (globalTA[i])
                {
                    gcTA_Destroy(globalTA[i]);
                    globalTA[i] = gcvNULL;
                }
            }

            Device->device = gcvNULL;
        }

        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
        {
            if (Device->kernels[i] != gcvNULL)
            {
                Device->kernels[i] = gcvNULL;
            }
        }

        if (Device->internalLogical != gcvNULL)
        {
            /* Unmap the internal memory. */
            iounmap(Device->internalLogical);
            Device->internalLogical = gcvNULL;
        }

        if (Device->internalVidMem != gcvNULL)
        {
            /* Destroy the internal heap. */
            gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
            Device->internalVidMem = gcvNULL;
        }

        for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
        {
            if (Device->extSRAMPhysical[i] != gcvNULL)
            {
                gckOS_ReleaseReservedMemory(
                    Device->os,
                    Device->extSRAMPhysical[i]
                    );
                Device->extSRAMPhysical[i] = gcvNULL;
            }

            if (Device->extSRAMVidMem[i] != gcvNULL)
            {
                gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->extSRAMVidMem[i]));
                Device->extSRAMVidMem[i] = gcvNULL;
            }
        }

        if (Device->externalPhysical != gcvNULL)
        {
            gckOS_ReleaseReservedMemory(
                Device->os,
                Device->externalPhysical
                );
            Device->externalPhysical = gcvNULL;
        }

        if (Device->externalLogical != gcvNULL)
        {
            Device->externalLogical = gcvNULL;
        }

        if (Device->externalVidMem != gcvNULL)
        {
            /* destroy the external heap */
            gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
            Device->externalVidMem = gcvNULL;
        }

        /*
         * Destroy contiguous memory pool after gckDEVICE destroyed. gckDEVICE
         * may allocates GPU memory types from SYSTEM pool.
         */
        if (Device->contiguousPhysical != gcvNULL)
        {
            if (Device->requestedContiguousBase == 0)
            {
                gcmkVERIFY_OK(_FreeMemory(
                    Device,
                    Device->contiguousLogical,
                    Device->contiguousPhysical
                    ));
            }
            else
            {
                gckOS_ReleaseReservedMemory(
                    Device->os,
                    Device->contiguousPhysical
                    );
                Device->contiguousPhysical = gcvNULL;
                Device->requestedContiguousBase = 0;
                Device->requestedContiguousSize = 0;
            }

            Device->contiguousLogical  = gcvNULL;
            Device->contiguousPhysical = gcvNULL;
        }

        if (Device->contiguousVidMem != gcvNULL)
        {
            /* Destroy the contiguous heap. */
            gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
            Device->contiguousVidMem = gcvNULL;
        }

        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
        {
            if (Device->registerBases[i])
            {
                /* Unmap register memory. */
                if (Device->requestedRegisterMemBases[i] != 0)
                {
                    iounmap(Device->registerBases[i]);
                    release_mem_region(Device->requestedRegisterMemBases[i],
                            Device->requestedRegisterMemSizes[i]);
                }

                Device->registerBases[i] = gcvNULL;
                Device->requestedRegisterMemBases[i] = 0;
                Device->requestedRegisterMemSizes[i] = 0;
            }
        }


        if (Device->taos)
        {
            gcmkVERIFY_OK(gctaOS_DestroyOS(Device->taos));
            Device->taos = gcvNULL;
        }

        /* Destroy the gckOS object. */
        if (Device->os != gcvNULL)
        {
            gcmkVERIFY_OK(gckOS_Destroy(Device->os));
            Device->os = gcvNULL;
        }

        _DebugfsCleanup(Device);

        /* Free the device. */
        kfree(Device);
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

/*******************************************************************************
**
**  gckGALDEVICE_Start
**
**  Start the gal device, including the following actions: setup the isr routine
**  and start the daemoni thread.
**
**  INPUT:
**
**      gckGALDEVICE Device
**          Pointer to an gckGALDEVICE object.
**
**  OUTPUT:
**
**      Nothing.
**
**  RETURNS:
**
**      gcvSTATUS_OK
**          Start successfully.
*/
gceSTATUS
gckGALDEVICE_Start(
    IN gckGALDEVICE Device
    )
{
    gctUINT i;
    gceSTATUS status = gcvSTATUS_OK;

    gcmkHEADER_ARG("Device=%p", Device);

    /* Start the kernel threads. */
    for (i = 0; i < gcvCORE_COUNT; ++i)
    {
        if (i == gcvCORE_VG)
        {
            continue;
        }

        gcmkONERROR(_StartThread(Device, i));
    }

    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        if (Device->kernels[i] == gcvNULL)
        {
            continue;
        }

        /* Setup the ISR routine. */
        gcmkONERROR(_SetupIsr(i));

        if (i == gcvCORE_VG)
        {
        }
        else
        {
            /* Switch to SUSPEND power state. */
            gcmkONERROR(gckHARDWARE_SetPowerState(
                Device->kernels[i]->hardware, gcvPOWER_OFF_BROADCAST
                ));

            gcmkONERROR(gckHARDWARE_StartTimerReset(Device->kernels[i]->hardware));
        }
    }

OnError:
    gcmkFOOTER();
    return status;
}

/*******************************************************************************
**
**  gckGALDEVICE_Stop
**
**  Stop the gal device, including the following actions: stop the daemon
**  thread, release the irq.
**
**  INPUT:
**
**      gckGALDEVICE Device
**          Pointer to an gckGALDEVICE object.
**
**  OUTPUT:
**
**      Nothing.
**
**  RETURNS:
**
**      Nothing.
*/
gceSTATUS
gckGALDEVICE_Stop(
    gckGALDEVICE Device
    )
{
    gctUINT i;
    gceSTATUS status = gcvSTATUS_OK;

    gcmkHEADER_ARG("Device=%p", Device);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        if (Device->kernels[i] == gcvNULL)
        {
            continue;
        }

        if (i == gcvCORE_VG)
        {
        }
        else
        {
            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                Device->kernels[i]->hardware, gcvTRUE
                ));

            /* Switch to OFF power state. */
            gcmkONERROR(gckHARDWARE_SetPowerState(
                Device->kernels[i]->hardware, gcvPOWER_OFF
                ));

            gckHARDWARE_StartTimerReset(Device->kernels[i]->hardware);
        }

        /* Stop the ISR routine. */
        gcmkONERROR(_ReleaseIsr(i));

    }

    /* Stop the kernel thread. */
    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        _StopThread(Device, i);
    }

OnError:
    gcmkFOOTER();
    return status;
}

