/* * ======== Timer_reconfig ======== * * 1. Init obj using params * 2. Timer_init() * 3. Configure timer (wrt emulation, frequency, etc.) * 4. Set period * 5. Timer_start() * */ Void Timer_reconfig (Timer_Object *obj, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { obj->controlRegInit = params->controlRegInit.source; obj->runMode = params->runMode; obj->startMode = params->startMode; obj->period = params->period; obj->periodType = params->periodType; obj->prevThreshold = params->prevThreshold; obj->synchronous = params->synchronous; if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); } } obj->arg = params->arg; obj->tickFxn = tickFxn; if (params->extFreq.lo) { /* (extFreq.hi is ignored) */ obj->frequency.lo = params->extFreq.lo; } postInit(obj, eb); if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } }
/* * ======== Timer_reconfig ======== * 1. Init obj using params * 2. Reconfig Hwi * 3. Timer_init() * 4. Timer configuration (wrt emulation, external frequency etc) * 5. Timer_setPeriod() * 6. Timer_start() */ Void Timer_reconfig (Timer_Object *obj, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { Hwi_Params hwiParams; obj->runMode = params->runMode; obj->startMode = params->startMode; obj->altclk = params->altclk; obj->period = params->period; obj->periodType = params->periodType; obj->prevThreshold = params->prevThreshold; obj->rollovers = 0; obj->savedCurrCount = 0; if (obj->altclk) { /* if using altclk the freq is always 16MHz */ obj->extFreq.lo = 16000000; obj->extFreq.hi = 0; } else { /* else use specified extFreq */ obj->extFreq.lo = params->extFreq.lo; obj->extFreq.hi = params->extFreq.hi; } if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); } } obj->arg = params->arg; obj->tickFxn = tickFxn; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } hwiParams.arg = (UArg)obj; Hwi_reconfig (obj->hwi, Timer_isrStub, &hwiParams); } Timer_postInit(obj, eb); if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } }
/* * ======== Timer_reconfig ======== * 1. Init obj using params * 2. Reconfig Hwi * 3. Timer_init() * 4. Timer configuration (wrt emulation, external frequency etc) * 5. Timer_setPeriod() * 6. Timer_start() */ Void Timer_reconfig (Timer_Object *obj, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { Hwi_Params hwiParams; obj->runMode = params->runMode; obj->startMode = params->startMode; obj->period = params->period; obj->periodType = params->periodType; if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); } } obj->arg = params->arg; obj->tickFxn = tickFxn; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } if (obj->id == 0) { hwiParams.arg = (UArg)obj; if (obj->runMode == Timer_RunMode_CONTINUOUS) { Hwi_reconfig (obj->hwi, Timer_periodicStub, &hwiParams); } else { Hwi_reconfig (obj->hwi, Timer_oneShotStub, &hwiParams); } } else { hwiParams.arg = obj->arg; Hwi_reconfig (obj->hwi, obj->tickFxn, &hwiParams); } } postInit(obj, eb); if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } }
/* * ======== Timer_deviceConfig ======== * Configure the timer. */ Int Timer_deviceConfig(Timer_Object *obj, Error_Block *eb) { TimerRegs *timer; UInt hwiKey; timer = (TimerRegs *)Timer_module->device[obj->id].baseAddr; /* reset the timer */ timer->tiocpCfg = obj->tiocpCfg | 0x2; /* wait for reset to finish */ while(timer->tistat != 0x01) ; /* initialize the timer */ Timer_initDevice(obj, eb); hwiKey = Hwi_disable(); /* set the period */ if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Hwi_restore(hwiKey); Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); return (3); } } else { timer->tcrr = Timer_MAX_PERIOD - obj->period; while (timer->twps & TIMER_TWPS_W_PEND_TCRR) ; timer->tldr = Timer_MAX_PERIOD - obj->period; while (timer->twps & TIMER_TWPS_W_PEND_TLDR) ; } timer->tmar = obj->tmar; while (timer->twps & TIMER_TWPS_W_PEND_TMAR) ; timer->twer = obj->twer; timer->tclr = obj->tclr; while (timer->twps & TIMER_TWPS_W_PEND_TCLR) ; Hwi_restore(hwiKey); return (0); }
/* * ======== postInit ======== */ static Int postInit(Timer_Object *obj, Error_Block *eb) { UInt hwiKey; hwiKey = Hwi_disable(); initDevice(obj); if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); Hwi_restore(hwiKey); return (4); } } else { timerDevices[obj->id].load = obj->period; } Hwi_restore(hwiKey); return (0); }
/* * ======== Timer_Instance_init ======== * 1. Select timer based on id * 2. Mark timer as in use * 3. Save timer handle if necessary (needed by TimestampProvider on 64). * 4. Init obj using params * 5. Create Hwi if tickFxn !=NULL * 6. Timer_init() * 7. Timer configuration (wrt emulation, external frequency etc) * 8. Timer_setPeriod() * 9. Timer_start() */ Int Timer_Instance_init(Timer_Object *obj, Int id, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { UInt key; Int status; Hwi_Params hwiParams; UInt tempId = 0xffff; if ((id != 0) && (id != Timer_ANY)) { Error_raise(eb, Timer_E_invalidTimer, id, 0); return (1); } key = Hwi_disable(); if (id == Timer_ANY) { if ((Timer_anyMask & 1) && (Timer_module->availMask & 1)) { Timer_module->availMask &= ~(1); tempId = 0; } } else if (Timer_module->availMask & 1) { Timer_module->availMask &= ~(1); tempId = id; } Hwi_restore(key); obj->staticInst = FALSE; if (tempId == 0xffff) { Error_raise(eb, Timer_E_notAvailable, id, 0); return (NO_TIMER_AVAIL); } else { obj->id = tempId; } Timer_module->handle = obj; obj->runMode = params->runMode; obj->startMode = params->startMode; obj->period = params->period; obj->periodType = params->periodType; obj->extFreq.lo = params->extFreq.lo; obj->extFreq.hi = params->extFreq.hi; if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); Hwi_restore(key); return (BAD_PERIOD); } } obj->arg = params->arg; obj->intNum = 15; obj->tickFxn = tickFxn; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } hwiParams.arg = (UArg)obj; if (obj->runMode == Timer_RunMode_CONTINUOUS) { obj->hwi = Hwi_create (obj->intNum, Timer_periodicStub, &hwiParams, eb); } else { obj->hwi = Hwi_create (obj->intNum, Timer_oneShotStub, &hwiParams, eb); } if (obj->hwi == NULL) { return (NO_HWI_OBJ); } } else { obj->hwi = NULL; } status = postInit(obj, eb); if (status) { return (status); } if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } return (0); }
/* * ======== Timer_Instance_init ======== * 1. Select timer based on id * 2. Mark timer as in use * 3. Save timer handle if necessary (needed by TimestampProvider on 64). * 4. Init obj using params * 5. Create Hwi if tickFxn !=NULL * 6. Timer_init() * 7. Timer configuration (wrt emulation, external frequency etc) * 8. Timer_setPeriod() * 9. Timer_start() */ Int Timer_Instance_init(Timer_Object *obj, Int id, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { UInt key; Int i, status; Hwi_Params hwiParams; UInt tempId = 0xffff; if (id >= Timer_NUM_TIMER_DEVICES) { if (id != Timer_ANY) { Error_raise(eb, Timer_E_invalidTimer, id, 0); return (1); } } key = Hwi_disable(); if (id == Timer_ANY) { for (i = 0; i < Timer_NUM_TIMER_DEVICES; i++) { if ((Timer_anyMask & (1 << i)) && (Timer_module->availMask & (1 << i))) { Timer_module->availMask &= ~(1 << i); tempId = i; break; } } } else if (Timer_module->availMask & (1 << id)) { Timer_module->availMask &= ~(1 << id); tempId = id; } Hwi_restore(key); obj->staticInst = FALSE; if (tempId == 0xffff) { Error_raise(eb, Timer_E_notAvailable, id, 0); return (2); } else { obj->id = tempId; } /* if timer id == 0 */ if (obj->id == 0) { obj->ctmid = 0; obj->intNum = 17; } else if (obj->id == 1) { obj->ctmid = 1; obj->intNum = 18; } obj->runMode = params->runMode; obj->startMode = params->startMode; obj->period = params->period; obj->periodType = params->periodType; obj->extFreq.lo = params->extFreq.lo; obj->extFreq.hi = params->extFreq.hi; if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); Hwi_restore(key); return (4); } } obj->arg = params->arg; obj->tickFxn = tickFxn; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } /* CTM doesn't need to be acknowledged, no stub required */ hwiParams.arg = obj->arg; obj->hwi = Hwi_create (obj->intNum, obj->tickFxn, &hwiParams, eb); if (obj->hwi == NULL) { return (3); } } else { obj->hwi = NULL; } Timer_module->handles[obj->id] = obj; status = Timer_postInit(obj, eb); if (status) { return (status); } if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } return (0); }
/* * ======== Timer_Instance_init ======== * 1. Select timer based on id * 2. Mark timer as in use * 3. Save timer handle if necessary (needed by TimestampProvider on 64). * 4. Init obj using params * 5. Create Hwi if tickFxn !=NULL * 6. Timer_init() * 7. Timer configuration (wrt emulation, external frequency etc) * 8. Timer_setPeriod() * 9. Timer_start() */ Int Timer_Instance_init(Timer_Object *obj, Int id, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { UInt key; Int i, status; Hwi_Params hwiParams; UInt tempId = 0xffff; if (id >= Timer_NUM_TIMER_DEVICES) { if (id != Timer_ANY) { Error_raise(eb, Timer_E_invalidTimer, id, 0); return (1); } } key = Hwi_disable(); if (id == Timer_ANY) { for (i = 0; i < Timer_NUM_TIMER_DEVICES; i++) { if ((Timer_anyMask & (1 << i)) && (Timer_module->availMask & (1 << i))) { Timer_module->availMask &= ~(1 << i); tempId = i; break; } } } else if (Timer_module->availMask & (1 << id)) { Timer_module->availMask &= ~(1 << id); tempId = id; } Hwi_restore(key); obj->staticInst = FALSE; if (tempId == 0xffff) { Error_raise(eb, Timer_E_notAvailable, id, 0); return (2); } else { obj->id = tempId; } /* if timer id == 0, use systick */ if (obj->id == 0) { obj->ctmid = 0; obj->intNum = 15; } /* if timer id == 1, must select which CTM timer based on core id */ else { if (Core_getId() == 0) { obj->ctmid = 0; obj->intNum = 18; } else { obj->ctmid = 1; obj->intNum = 22; } } obj->runMode = params->runMode; obj->startMode = params->startMode; obj->period = params->period; obj->periodType = params->periodType; obj->extFreq.lo = params->extFreq.lo; obj->extFreq.hi = params->extFreq.hi; if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); Hwi_restore(key); return (4); } } obj->arg = params->arg; obj->tickFxn = tickFxn; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } /* we'll enable the interrupt when we're ready */ hwiParams.enableInt = FALSE; /* SysTick needs to be acknowledged, use stub functions */ if (obj->id == 0) { hwiParams.arg = (UArg)obj; if (obj->runMode == Timer_RunMode_CONTINUOUS) { obj->hwi = Hwi_create (obj->intNum, Timer_periodicStub, &hwiParams, eb); } else { obj->hwi = Hwi_create (obj->intNum, Timer_oneShotStub, &hwiParams, eb); } } /* CTM doesn't need to be acknowledged, no stub required */ else { hwiParams.arg = obj->arg; obj->hwi = Hwi_create (obj->intNum, obj->tickFxn, &hwiParams, eb); } if (obj->hwi == NULL) { return (3); } } else { obj->hwi = NULL; } Timer_module->handles[obj->id] = obj; status = postInit(obj, eb); if (status) { return (status); } if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } return (0); }
/* * ======== Timer_deviceConfig ======== * Configure the timer. */ Int Timer_deviceConfig(Timer_Object *obj, Error_Block *eb) { TimerRegs *timer; UInt hwiKey; UInt32 tsicr; timer = (TimerRegs *)Timer_module->device[obj->id].baseAddr; /* initialize the timer */ Timer_initDevice(obj, eb); hwiKey = Hwi_disable(); /* if doing SOFTRESET: do it first before setting other flags */ if (obj->tiocpCfg & TIMER_TIOCP_CFG_SOFTRESET_FLAG) { timer->tiocpCfg = TIMER_TIOCP_CFG_SOFTRESET_FLAG; while (timer->tiocpCfg & TIMER_TIOCP_CFG_SOFTRESET_FLAG) ; } timer->tiocpCfg = obj->tiocpCfg & ~TIMER_TIOCP_CFG_SOFTRESET_FLAG; /* xfer 'posted' setting if not current */ tsicr = timer->tsicr; if (obj->tsicr & TIMER_TSICR_POSTED) { if ((tsicr & TIMER_TSICR_POSTED) == 0) { timer->tsicr = (tsicr | TIMER_TSICR_POSTED); } } else { if ((tsicr & TIMER_TSICR_POSTED) != 0) { timer->tsicr = (tsicr & ~TIMER_TSICR_POSTED); } } /* set the period */ if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Hwi_restore(hwiKey); Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); return (3); } } else { if (obj->runMode != Timer_RunMode_DYNAMIC) { timer->tcrr = Timer_MAX_PERIOD - obj->period; while (timer->twps & TIMER_TWPS_W_PEND_TCRR) ; timer->tldr = Timer_MAX_PERIOD - obj->period; while (timer->twps & TIMER_TWPS_W_PEND_TLDR) ; } else { timer->tcrr = 0; while (timer->twps & TIMER_TWPS_W_PEND_TCRR) ; timer->tmar = obj->period; while (timer->twps & TIMER_TWPS_W_PEND_TMAR) ; } } if (obj->runMode != Timer_RunMode_DYNAMIC) { timer->tmar = obj->tmar; while (timer->twps & TIMER_TWPS_W_PEND_TMAR) ; } timer->twer = obj->twer; timer->tier = obj->tier; timer->tclr = obj->tclr; while (timer->twps & TIMER_TWPS_W_PEND_TCLR) ; Hwi_restore(hwiKey); return (0); }
/* * ======== Timer_Instance_init ======== * 1. Select timer based on id * 2. Mark timer as in use * 3. Save timer handle if necessary * 4. Init obj using params * 5. Create Hwi if tickFxn !=NULL * 6. Timer_init() * 7. Timer configuration (wrt emulation, external frequency etc) * 8. Timer_setPeriod() * 9. Timer_start() */ Int Timer_Instance_init(Timer_Object *obj, Int id, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb) { UInt key; Int i, status; Hwi_Params hwiParams; UInt tempId = 0xffff; if (id >= Timer_numTimerDevices) { if (id != Timer_ANY) { Error_raise(eb, Timer_E_invalidTimer, id, 0); return (1); } } key = Hwi_disable(); if (id == Timer_ANY) { for (i = 0; i < Timer_numTimerDevices; i++) { if ((Timer_anyMask & (1 << i)) && (Timer_module->availMask & (1 << i))) { Timer_module->availMask &= ~(1 << i); tempId = i; break; } } } else if (Timer_module->availMask & (1 << id)) { Timer_module->availMask &= ~(1 << id); tempId = id; } Hwi_restore(key); obj->staticInst = FALSE; if (tempId == 0xffff) { Error_raise(eb, Timer_E_notAvailable, id, 0); return (2); } else { obj->id = tempId; } obj->runMode = params->runMode; obj->startMode = params->startMode; if (params->altclk && !Timer_supportsAltclk) { Error_raise(eb, Timer_E_noaltclk, id, 0); return (1); } obj->altclk = params->altclk; obj->period = params->period; obj->periodType = params->periodType; if (obj->altclk) { /* if using altclk the freq is always 16MHz */ obj->extFreq.lo = 16000000; obj->extFreq.hi = 0; } else { /* else use specified extFreq */ obj->extFreq.lo = params->extFreq.lo; obj->extFreq.hi = params->extFreq.hi; } obj->arg = params->arg; obj->intNum = Timer_module->device[obj->id].intNum; obj->tickFxn = tickFxn; obj->prevThreshold = params->prevThreshold; obj->rollovers = 0; obj->savedCurrCount = 0; if (obj->tickFxn) { if (params->hwiParams) { Hwi_Params_copy(&hwiParams, (params->hwiParams)); } else { Hwi_Params_init(&hwiParams); } hwiParams.arg = (UArg)obj; obj->hwi = Hwi_create (obj->intNum, Timer_isrStub, &hwiParams, eb); if (obj->hwi == NULL) { return (3); } } else { obj->hwi = NULL; } Timer_module->handles[obj->id] = obj; /* enable and reset the timer */ Timer_enableFunc(obj->id); Timer_initDevice(obj); if (obj->periodType == Timer_PeriodType_MICROSECS) { if (!Timer_setPeriodMicroSecs(obj, obj->period)) { Error_raise(eb, Timer_E_cannotSupport, obj->period, 0); Hwi_restore(key); return (4); } } status = Timer_postInit(obj, eb); if (status) { return (status); } if (obj->startMode == Timer_StartMode_AUTO) { Timer_start(obj); } return (0); }
/* * ======== HdmiWa_taskFxn ======== */ static Void HdmiWa_taskFxn(UArg arg0, UArg arg1) { MessageQCopy_Handle handle; UInt32 myEndpoint = 0; UInt32 remoteEndpoint; UInt16 dstProc; UInt16 len; UInt32 temp; UInt32 ctsInterval = 0; UInt32 timerPeriod = 0; HdmiWa_PayloadData payload; System_printf("HdmiWa_taskFxn Entered...:\n"); dstProc = MultiProc_getId("HOST"); MessageQCopy_init(dstProc); /* Create the messageQ for receiving (and get our endpoint for sending). */ handle = MessageQCopy_create(70, &myEndpoint); NameMap_register("rpmsg-hdmiwa", 70); while (TRUE) { /* Await a character message: */ MessageQCopy_recv(handle, (Ptr)&payload, &len, &remoteEndpoint, MessageQCopy_FOREVER); if (!payload.trigger) { System_printf("HDMI payload received CTSInterval = %d, " "ACRRate = %d, SysCLK = %d\n", payload.ctsInterval, payload.acrRate, payload.sysClockFreq); if (!payload.ctsInterval || !payload.acrRate || !payload.sysClockFreq) { System_printf("Stop ACR WA, set auto reload timer to " "default periodicity\n"); module->waEnable = FALSE; timerPeriod = Clock_tickPeriod; goto set_timer; } /* ACR period in microseconds */ timerPeriod = 1000000 / payload.acrRate; ctsInterval = TIME_IN_NS_TO_GPT_CYCLES(payload.ctsInterval, payload.sysClockFreq); /* Set 1ms interval*/ temp = ONE_MILLISECOND % payload.ctsInterval; if (temp < TEN_MICROSECONDS) { module->ctsIntervalDelta = 1; } else { module->ctsIntervalDelta = TIME_IN_NS_TO_GPT_CYCLES(temp, payload.sysClockFreq); } /* Set ACR in SW mode */ REG32(HDMI_ACR_CTRL) = HDMI_CTS_SEL_SW; REG32(HDMI_INTR2) = HDMI_CTS_CHG_INT; REG32(HDMI_FREQ_SVAL) = HDMI_FREQ_SVAL_MCLK_IS_1024_FS; while (REG32(HDMI_FREQ_SVAL) != HDMI_FREQ_SVAL_MCLK_IS_1024_FS); temp = module->pTmr->tcrr; temp += module->ctsIntervalDelta; while (module->pTmr->tcrr < temp); REG32(HDMI_FREQ_SVAL) = HDMI_FREQ_SVAL_MCLK_IS_128_FS; for (temp = 0; (temp < 100000) && ((REG32(HDMI_INTR2) & HDMI_CTS_CHG_INT) != HDMI_CTS_CHG_INT); temp++); REG32(HDMI_INTR2) = HDMI_CTS_CHG_INT; module->gptTcrrHalfCts = ctsInterval / 2; module->gptTcrrFullCts = ctsInterval; set_timer: System_printf("Autoreload timer to %d\n", timerPeriod); Timer_setPeriodMicroSecs(SysM3TickTmr, timerPeriod); Timer_start(SysM3TickTmr); MessageQCopy_send(dstProc, remoteEndpoint, myEndpoint, (Ptr)&payload, len); } else { System_printf("Start HDMI ACRWA\n"); module->waEnable = TRUE; } } }