static void _TimerFunction( gctPOINTER Data ) { gceSTATUS status = gcvSTATUS_OK; gckDVFS dvfs = (gckDVFS) Data; gckHARDWARE hardware = dvfs->hardware; gctUINT32 value; gctUINT32 frequency; gctUINT8 scale; gctUINT32 t1, t2, consumed; gckOS_GetTicks(&t1); gcmkONERROR(gckHARDWARE_QueryLoad(hardware, &value)); /* determine target sacle. */ _Policy(dvfs, value, &scale); /* Set frequency and voltage. */ gcmkONERROR(gckOS_SetGPUFrequency(hardware->os, hardware->core, scale)); /* Query real frequency. */ gcmkONERROR( gckOS_QueryGPUFrequency(hardware->os, hardware->core, &frequency, &dvfs->currentScale)); _RecordFrequencyHistory(dvfs, frequency); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_POWER, "Current frequency = %d", frequency); /* Set period. */ gcmkONERROR(gckHARDWARE_SetDVFSPeroid(hardware, frequency)); OnError: /* Determine next querying time. */ gckOS_GetTicks(&t2); consumed = gcmMIN(((long)t2 - (long)t1), 5); if (dvfs->stop == gcvFALSE) { gcmkVERIFY_OK(gckOS_StartTimer(hardware->os, dvfs->timer, dvfs->pollingTime - consumed)); } return; }
/* echo xx > /proc/driver/gc set ... */ static ssize_t gc_proc_write(struct file *file, const char *buff, size_t len, loff_t *off) { char messages[256]; if(len > 256) len = 256; if(copy_from_user(messages, buff, len)) return -EFAULT; printk("\n"); if(strncmp(messages, "printPID", 8) == 0) { galDevice->printPID = galDevice->printPID ? gcvFALSE : gcvTRUE; printk("==>Change printPID to %s\n", galDevice->printPID ? "gcvTRUE" : "gcvFALSE"); } else if(strncmp(messages, "profile", 7) == 0) { gctUINT32 idleTime, timeSlice; gctUINT32 start,end; timeSlice = 10000; start = gckOS_GetTicks(); gckOS_IdleProfile(galDevice->os, &timeSlice, &idleTime); end = gckOS_GetTicks(); printk("idle:total [%d, %d]\n", idleTime, timeSlice); printk("profile cost %d\n", end - start); } else if(strncmp(messages, "hang", 4) == 0) { galDevice->kernel->hardware->hang = galDevice->kernel->hardware->hang ? gcvFALSE : gcvTRUE; } else if(strncmp(messages, "reset", 5) == 0) { galDevice->reset = galDevice->reset ? gcvFALSE : gcvTRUE; } #ifdef CONFIG_PXA_DVFM else if(strncmp(messages, "d2debug", 7) == 0) { galDevice->needD2DebugInfo = galDevice->needD2DebugInfo ? gcvFALSE : gcvTRUE; } else if(strncmp(messages, "D1", 2) == 0) { galDevice->enableD1 = galDevice->enableD1 ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "D2", 2) == 0) { galDevice->enableD2 = galDevice->enableD2 ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "D0", 2) == 0) { galDevice->enableD0CS= galDevice->enableD0CS ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "CG", 2) == 0) { galDevice->enableCG= galDevice->enableCG ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "needreset", 9) == 0) { galDevice->needResetAfterD2 = galDevice->needResetAfterD2 ? gcvFALSE : gcvTRUE; } #endif else if(strncmp(messages, "su", 2) == 0) { gceSTATUS status; if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_OFF) { status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_OFF); if (gcmIS_ERROR(status)) { return -1; } gckOS_SuspendInterrupt(galDevice->os); gckOS_ClockOff(); } } else if(strncmp(messages, "re", 2) == 0) { gceSTATUS status; if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_ON) { gckOS_ClockOn(0); gckOS_ResumeInterrupt(galDevice->os); status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_ON); if (gcmIS_ERROR(status)) { return -1; } } } else if(strncmp(messages, "stress", 6) == 0) { int i; /* struct vmalloc_info vmi; */ /* {get_vmalloc_info(&vmi);printk("%s,%d,VmallocUsed: %8lu kB\n",__func__,__LINE__,vmi.used >> 10); } */ #ifdef _DEBUG gckOS_SetDebugLevel(gcvLEVEL_VERBOSE); gckOS_SetDebugZone(1023); #endif for(i=0;i<20000;i++) { gceSTATUS status; static int count = 0; printk("count:%d\n",count++); printk("!!!\t"); if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_OFF) { status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_OFF); if (gcmIS_ERROR(status)) { return -1; } gckOS_SuspendInterrupt(galDevice->os); gckOS_ClockOff(); } printk("@@@\t"); if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_ON) { gckOS_ClockOn(0); gckOS_ResumeInterrupt(galDevice->os); status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_ON); if (gcmIS_ERROR(status)) { return -1; } } printk("###\n"); } } else if(strncmp(messages, "debug", 5) == 0) { #ifdef _DEBUG static int count = 0; if(count%2 == 0) { gckOS_SetDebugLevel(gcvLEVEL_VERBOSE); gckOS_SetDebugZone(1023); } else { gckOS_SetDebugLevel(gcvLEVEL_NONE); gckOS_SetDebugZone(0); } count++; #endif } else if(strncmp(messages, "16", 2) == 0) { printk("frequency change to 1/16\n"); /* frequency change to 1/16 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x210)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x010)); } else if(strncmp(messages, "32", 2) == 0) { printk("frequency change to 1/32\n"); /* frequency change to 1/32*/ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x208)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x008)); } else if(strncmp(messages, "64", 2) == 0) { printk("frequency change to 1/64\n"); /* frequency change to 1/64 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x204)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x004)); } else if('1' == messages[0]) { printk("frequency change to full speed\n"); /* frequency change to full speed */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x300)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x100)); } else if('2' == messages[0]) { printk("frequency change to 1/2\n"); /* frequency change to 1/2 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x280)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x080)); } else if('4' == messages[0]) { printk("frequency change to 1/4\n"); /* frequency change to 1/4 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x240)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x040)); } else if('8' == messages[0]) { printk("frequency change to 1/8\n"); /* frequency change to 1/8 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x220)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x020)); } else { printk("unknown echo\n"); } return len; }