hw/timer/cmsdk-apb-dualtimer: Convert to use Clock input
Switch the CMSDK APB dualtimer device over to using its Clock input; the pclk-frq property is now ignored. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Luc Michel <luc@lmichel.fr> Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20210128114145.20536-20-peter.maydell@linaro.org Message-id: 20210121190622.22000-20-peter.maydell@linaro.org Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
This commit is contained in:
parent
5e066562f5
commit
7208aafb6c
@ -106,6 +106,22 @@ static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
|
||||
qemu_set_irq(s->timerintc, timintc);
|
||||
}
|
||||
|
||||
static int cmsdk_dualtimermod_divisor(CMSDKAPBDualTimerModule *m)
|
||||
{
|
||||
/* Return the divisor set by the current CONTROL.PRESCALE value */
|
||||
switch (FIELD_EX32(m->control, CONTROL, PRESCALE)) {
|
||||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return 16;
|
||||
case 2:
|
||||
case 3: /* UNDEFINED, we treat like 2 (and complained when it was set) */
|
||||
return 256;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
|
||||
uint32_t newctrl)
|
||||
{
|
||||
@ -146,7 +162,7 @@ static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor);
|
||||
ptimer_set_period_from_clock(m->timer, m->parent->timclk, divisor);
|
||||
}
|
||||
|
||||
if (changed & R_CONTROL_MODE_MASK) {
|
||||
@ -414,7 +430,8 @@ static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m)
|
||||
* limit must both be set to 0xffff, so we wrap at 16 bits.
|
||||
*/
|
||||
ptimer_set_limit(m->timer, 0xffff, 1);
|
||||
ptimer_set_freq(m->timer, m->parent->pclk_frq);
|
||||
ptimer_set_period_from_clock(m->timer, m->parent->timclk,
|
||||
cmsdk_dualtimermod_divisor(m));
|
||||
ptimer_transaction_commit(m->timer);
|
||||
}
|
||||
|
||||
@ -432,6 +449,20 @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
|
||||
s->timeritop = 0;
|
||||
}
|
||||
|
||||
static void cmsdk_apb_dualtimer_clk_update(void *opaque)
|
||||
{
|
||||
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
|
||||
CMSDKAPBDualTimerModule *m = &s->timermod[i];
|
||||
ptimer_transaction_begin(m->timer);
|
||||
ptimer_set_period_from_clock(m->timer, m->parent->timclk,
|
||||
cmsdk_dualtimermod_divisor(m));
|
||||
ptimer_transaction_commit(m->timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmsdk_apb_dualtimer_init(Object *obj)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
@ -446,7 +477,8 @@ static void cmsdk_apb_dualtimer_init(Object *obj)
|
||||
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
|
||||
sysbus_init_irq(sbd, &s->timermod[i].timerint);
|
||||
}
|
||||
s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
|
||||
s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
|
||||
cmsdk_apb_dualtimer_clk_update, s);
|
||||
}
|
||||
|
||||
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
|
||||
@ -454,8 +486,8 @@ static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
|
||||
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
|
||||
int i;
|
||||
|
||||
if (s->pclk_frq == 0) {
|
||||
error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
|
||||
if (!clock_has_source(s->timclk)) {
|
||||
error_setg(errp, "CMSDK APB dualtimer: TIMCLK clock must be connected");
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user