#include "pxa255_PwrClk.h" static Boolean pxa255pwrClkPrvCoprocRegXferFunc(struct ArmCpu* cpu, void* userData, Boolean two, Boolean read, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2){ Pxa255pwrClk* pc = userData; UInt32 val = 0; if(!read) val = cpuGetRegExternal(cpu, Rx); if(CRm == 0 && op2 == 0 && op1 == 0 && !two){ switch(CRn){ case 6: if(read) val = 0; else{ pc->turbo = (val & 1) != 0; if(val & 2){ err_str("Set speed mode"); // err_str("(CCCR + cp14 reg6) to 0x"); // err_hex(pc->CCCR); // err_str(", 0x"); // err_hex(val); // err_str("\r\n"); } } case 7: if(read) val = pc->turbo ? 1 : 0; else if(val != 0){ // fprintf(stderr, "Someone tried to set processor power mode (cp14 reg7) to 0x%08lX\n", val); } goto success; } } return false; success: if(read) cpuSetReg(cpu, Rx, val); return true; } static Boolean pxa255pwrClkPrvClockMgrMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){ Pxa255pwrClk* pc = userData; UInt32 val = 0; if(size != 4) { err_str(__FILE__ ": Unexpected "); // err_str(write ? "write" : "read"); // err_str(" of "); // err_dec(size); // err_str(" bytes to 0x"); // err_hex(pa); // err_str("\r\n"); return true; //we do not support non-word accesses } pa = (pa - PXA255_CLOCK_MANAGER_BASE) >> 2; if(write) val = *(UInt32*)buf; switch(pa){ case 0: //CCCR if(write) pc->CCCR = val; else val = pc->CCCR; break; case 1: //CKEN if(write) pc->CKEN = val; else val = pc->CKEN; break; case 2: //OSCR if(!write) val = pc->OSCR; //no writing to this register break; } if(!write) *(UInt32*)buf = val; return true; } static Boolean pxa255pwrClkPrvPowerMgrMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){ Pxa255pwrClk* pc = userData; UInt32 val = 0; if(size != 4) { err_str(__FILE__ ": Unexpected "); // err_str(write ? "write" : "read"); // err_str(" of "); // err_dec(size); // err_str(" bytes to 0x"); // err_hex(pa); // err_str("\r\n"); return true; //we do not support non-word accesses } pa = (pa - PXA255_POWER_MANAGER_BASE) >> 2; if(write) val = *(UInt32*)buf; if(pa < 13){ if(write) pc->pwrRegs[pa] = val; else val = pc->pwrRegs[pa]; } if(!write) *(UInt32*)buf = val; return true; } Boolean pxa255pwrClkInit(Pxa255pwrClk* pc, ArmCpu* cpu, ArmMem* physMem){ ArmCoprocessor cp; Boolean ok = true; __mem_zero(pc, sizeof(Pxa255pwrClk)); pc->cpu = cpu; pc->CCCR = 0x00000122UL; //set CCCR to almost default value (we use mult 32 not 27) pc->CKEN = 0x000179EFUL; //set CKEN to default value pc->OSCR = 0x00000003UL; //32KHz oscillator on and stable pc->pwrRegs[1] = 0x20; //set PSSR pc->pwrRegs[3] = 3; //set PWER pc->pwrRegs[4] = 3; //set PRER pc->pwrRegs[5] = 3; //set PFER pc->pwrRegs[12] = 1; //set RCSR cp.regXfer = pxa255pwrClkPrvCoprocRegXferFunc; cp.dataProcessing = NULL; cp.memAccess = NULL; cp.twoRegF = NULL; cp.userData = pc; cpuCoprocessorRegister(cpu, 14, &cp); ok = ok && memRegionAdd(physMem, PXA255_CLOCK_MANAGER_BASE, PXA255_CLOCK_MANAGER_SIZE, pxa255pwrClkPrvClockMgrMemAccessF, pc); ok = ok && memRegionAdd(physMem, PXA255_POWER_MANAGER_BASE, PXA255_POWER_MANAGER_SIZE, pxa255pwrClkPrvPowerMgrMemAccessF, pc); return ok; }