gceSTATUS
gckKERNEL_Construct(
	IN gckOS Os,
	IN gctPOINTER Context,
	OUT gckKERNEL * Kernel
	)
{
	gckKERNEL kernel = gcvNULL;
	gceSTATUS status;

	gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);

	/* Verify the arguments. */
	gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
	gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);

	/* Allocate the gckKERNEL object. */
	gcmkONERROR(
		gckOS_Allocate(Os,
					   gcmSIZEOF(struct _gckKERNEL),
					   (gctPOINTER *) &kernel));
#if MRVL_LOW_POWER_MODE_DEBUG
    gcmERR_RETURN(
		gckOS_Allocate(Os, 0x1000000, (gctPOINTER *) &kernel->kernelMSG));

    kernel->msgLen = 0;
#endif

	/* Zero the object pointers. */
	kernel->hardware = gcvNULL;
	kernel->command  = gcvNULL;
	kernel->event    = gcvNULL;
	kernel->mmu      = gcvNULL;

	/* Initialize the gckKERNEL object. */
	kernel->object.type = gcvOBJ_KERNEL;
	kernel->os          = Os;

	/* Save context. */
	kernel->context = Context;

    /* Construct atom holding number of clients. */
    kernel->atomClients = gcvNULL;
    gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
#if gcdSECURE_USER
    kernel->cacheSlots     = 0;
    kernel->cacheTimeStamp = 0;
#endif

	/* Construct the gckHARDWARE object. */
	gcmkONERROR(
		gckHARDWARE_Construct(Os, &kernel->hardware));

	/* Set pointer to gckKERNEL object in gckHARDWARE object. */
	kernel->hardware->kernel = kernel;

	/* Initialize the hardware. */
	gcmkONERROR(
		gckHARDWARE_InitializeHardware(kernel->hardware));

	/* Construct the gckCOMMAND object. */
	gcmkONERROR(
		gckCOMMAND_Construct(kernel, &kernel->command));

	/* Construct the gckEVENT object. */
	gcmkONERROR(
		gckEVENT_Construct(kernel, &kernel->event));

	/* Construct the gckMMU object. */
	gcmkONERROR(
		gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
	kernel->notifyIdle = gcvTRUE; /* gcvFALSE; */

#if VIVANTE_PROFILER
	/* Initialize profile setting */
#if defined ANDROID
	kernel->profileEnable = gcvFALSE;
#else
	kernel->profileEnable = gcvTRUE;
#endif

	gcmkVERIFY_OK(
		gckOS_MemCopy(kernel->profileFileName,
					  DEFAULT_PROFILE_FILE_NAME,
					  gcmSIZEOF(DEFAULT_PROFILE_FILE_NAME) + 1));
#endif

	/* Return pointer to the gckKERNEL object. */
	*Kernel = kernel;

	/* Success. */
	gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
	return gcvSTATUS_OK;

OnError:
	if (kernel != gcvNULL)
	{
    	if (kernel->event != gcvNULL)
	    {
    	    gcmkVERIFY_OK(gckEVENT_Destroy(kernel->event));
    	}

   	 	if (kernel->command != gcvNULL)
    	{
		gcmkVERIFY_OK(gckCOMMAND_Destroy(kernel->command));
    	}

    	if (kernel->hardware != gcvNULL)
    	{
        	gcmkVERIFY_OK(gckHARDWARE_Destroy(kernel->hardware));
    	}

        if (kernel->atomClients != gcvNULL)
        {
            gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
        }

    kernel->version = _GC_VERSION_STRING_;

#if MRVL_LOW_POWER_MODE_DEBUG
	gcmkVERIFY_OK(
		gckOS_Free(Os, kernel->kernelMSG));
#endif
    	gcmkVERIFY_OK(gckOS_Free(Os, kernel));
	}

	/* Return the error. */
	gcmkFOOTER();
	return status;
}
gceSTATUS _power_on_gc(gckGALDEVICE device)
{
    /* turn on gc */
    if(device->kernel->hardware->chipPowerState != gcvPOWER_ON)
    {
        gceSTATUS status;

        // enable clock and irq
        {
            gckOS_ClockOn(0);
            gckOS_ResumeInterrupt(device->os);
        }
        // INITIALIZE
        {
            /* Initialize hardware. */
            gcmkONERROR(
                gckHARDWARE_InitializeHardware(device->kernel->hardware));

            gcmkONERROR(
                gckHARDWARE_SetFastClear(device->kernel->hardware,
                                         device->kernel->hardware->allowFastClear,
                                         device->kernel->hardware->allowCompression));

            /* Force the command queue to reload the next context. */
            device->kernel->command->currentContext = 0;
        }

        /* Sleep for 1ms, to make sure everything is powered on. */
//        mdelay(1);//gcmVERIFY_OK(gcoOS_Delay(galDevice->os, 1));

        // start
        {
#if MUTEX_QUEUE
            /* Release the command mutex queue. */
            gcmkONERROR(
                gckOS_ReleaseMutex(device->kernel->hardware->os,
                                   device->kernel->command->mutexQueue));
#endif
            /* Start the command processor. */
            gcmkONERROR(
                gckCOMMAND_Start(device->kernel->command));
        }

        // release_context
        {
#if MUTEX_CONTEXT
            /* Release the context switching mutex. */
            gcmkVERIFY_OK(
                gckOS_ReleaseMutex(device->kernel->hardware->os,
                                   device->kernel->command->mutexContext));
#endif
        }

        printk("[%s]\t@%d\tC:0x%p\tQ:0x%p\n", __func__, __LINE__, device->kernel->command->mutexContext, device->kernel->command->mutexQueue);
        device->kernel->hardware->chipPowerState = gcvPOWER_ON;
        //galDevice->kernel->notifyIdle = gcvTRUE;
    }

    return gcvSTATUS_TRUE;
OnError:
    printk("ERROR: %s has error \n",__func__);

    return gcvSTATUS_FALSE;
}