hw/timer/exynos4210_mct.c: Switch GFRC to transaction-based ptimer API
We want to switch the exynos MCT code away from bottom-half based ptimers to the new transaction-based ptimer API. The MCT is complicated and uses multiple different ptimers, so it's clearer to switch it a piece at a time. Here we change over only the GFRC. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20191008171740.9679-12-peter.maydell@linaro.org
This commit is contained in:
parent
30e22c8733
commit
9ede4ec094
|
@ -364,6 +364,7 @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set counter of FRC global timer.
|
* Set counter of FRC global timer.
|
||||||
|
* Must be called within exynos4210_gfrc_tx_begin/commit block.
|
||||||
*/
|
*/
|
||||||
static void exynos4210_gfrc_set_count(Exynos4210MCTGT *s, uint64_t count)
|
static void exynos4210_gfrc_set_count(Exynos4210MCTGT *s, uint64_t count)
|
||||||
{
|
{
|
||||||
|
@ -385,6 +386,7 @@ static uint64_t exynos4210_gfrc_get_count(Exynos4210MCTGT *s)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stop global FRC timer
|
* Stop global FRC timer
|
||||||
|
* Must be called within exynos4210_gfrc_tx_begin/commit block.
|
||||||
*/
|
*/
|
||||||
static void exynos4210_gfrc_stop(Exynos4210MCTGT *s)
|
static void exynos4210_gfrc_stop(Exynos4210MCTGT *s)
|
||||||
{
|
{
|
||||||
|
@ -395,6 +397,7 @@ static void exynos4210_gfrc_stop(Exynos4210MCTGT *s)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start global FRC timer
|
* Start global FRC timer
|
||||||
|
* Must be called within exynos4210_gfrc_tx_begin/commit block.
|
||||||
*/
|
*/
|
||||||
static void exynos4210_gfrc_start(Exynos4210MCTGT *s)
|
static void exynos4210_gfrc_start(Exynos4210MCTGT *s)
|
||||||
{
|
{
|
||||||
|
@ -403,6 +406,21 @@ static void exynos4210_gfrc_start(Exynos4210MCTGT *s)
|
||||||
ptimer_run(s->ptimer_frc, 1);
|
ptimer_run(s->ptimer_frc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start ptimer transaction for global FRC timer; this is just for
|
||||||
|
* consistency with the way we wrap operations like stop and run.
|
||||||
|
*/
|
||||||
|
static void exynos4210_gfrc_tx_begin(Exynos4210MCTGT *s)
|
||||||
|
{
|
||||||
|
ptimer_transaction_begin(s->ptimer_frc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Commit ptimer transaction for global FRC timer. */
|
||||||
|
static void exynos4210_gfrc_tx_commit(Exynos4210MCTGT *s)
|
||||||
|
{
|
||||||
|
ptimer_transaction_commit(s->ptimer_frc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find next nearest Comparator. If current Comparator value equals to other
|
* Find next nearest Comparator. If current Comparator value equals to other
|
||||||
* Comparator value, skip them both
|
* Comparator value, skip them both
|
||||||
|
@ -492,6 +510,7 @@ static uint64_t exynos4210_gcomp_get_distance(Exynos4210MCTState *s, int32_t id)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restart global FRC timer
|
* Restart global FRC timer
|
||||||
|
* Must be called within exynos4210_gfrc_tx_begin/commit block.
|
||||||
*/
|
*/
|
||||||
static void exynos4210_gfrc_restart(Exynos4210MCTState *s)
|
static void exynos4210_gfrc_restart(Exynos4210MCTState *s)
|
||||||
{
|
{
|
||||||
|
@ -933,6 +952,19 @@ static void exynos4210_ltick_event(void *opaque)
|
||||||
exynos4210_ltick_int_start(&s->tick_timer);
|
exynos4210_ltick_int_start(&s->tick_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tx_ptimer_set_freq(ptimer_state *s, uint32_t freq)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* callers of exynos4210_mct_update_freq() never do anything
|
||||||
|
* else that needs to be in the same ptimer transaction, so
|
||||||
|
* to avoid a lot of repetition we have a convenience function
|
||||||
|
* for begin/set_freq/commit.
|
||||||
|
*/
|
||||||
|
ptimer_transaction_begin(s);
|
||||||
|
ptimer_set_freq(s, freq);
|
||||||
|
ptimer_transaction_commit(s);
|
||||||
|
}
|
||||||
|
|
||||||
/* update timer frequency */
|
/* update timer frequency */
|
||||||
static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
|
static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
|
||||||
{
|
{
|
||||||
|
@ -945,7 +977,7 @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
|
||||||
DPRINTF("freq=%dHz\n", s->freq);
|
DPRINTF("freq=%dHz\n", s->freq);
|
||||||
|
|
||||||
/* global timer */
|
/* global timer */
|
||||||
ptimer_set_freq(s->g_timer.ptimer_frc, s->freq);
|
tx_ptimer_set_freq(s->g_timer.ptimer_frc, s->freq);
|
||||||
|
|
||||||
/* local timer */
|
/* local timer */
|
||||||
ptimer_set_freq(s->l_timer[0].tick_timer.ptimer_tick, s->freq);
|
ptimer_set_freq(s->l_timer[0].tick_timer.ptimer_tick, s->freq);
|
||||||
|
@ -965,7 +997,9 @@ static void exynos4210_mct_reset(DeviceState *d)
|
||||||
|
|
||||||
/* global timer */
|
/* global timer */
|
||||||
memset(&s->g_timer.reg, 0, sizeof(s->g_timer.reg));
|
memset(&s->g_timer.reg, 0, sizeof(s->g_timer.reg));
|
||||||
|
exynos4210_gfrc_tx_begin(&s->g_timer);
|
||||||
exynos4210_gfrc_stop(&s->g_timer);
|
exynos4210_gfrc_stop(&s->g_timer);
|
||||||
|
exynos4210_gfrc_tx_commit(&s->g_timer);
|
||||||
|
|
||||||
/* local timer */
|
/* local timer */
|
||||||
memset(s->l_timer[0].reg.cnt, 0, sizeof(s->l_timer[0].reg.cnt));
|
memset(s->l_timer[0].reg.cnt, 0, sizeof(s->l_timer[0].reg.cnt));
|
||||||
|
@ -1144,7 +1178,9 @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
s->g_timer.reg.cnt = new_frc;
|
s->g_timer.reg.cnt = new_frc;
|
||||||
|
exynos4210_gfrc_tx_begin(&s->g_timer);
|
||||||
exynos4210_gfrc_restart(s);
|
exynos4210_gfrc_restart(s);
|
||||||
|
exynos4210_gfrc_tx_commit(&s->g_timer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case G_CNT_WSTAT:
|
case G_CNT_WSTAT:
|
||||||
|
@ -1168,7 +1204,9 @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
|
||||||
s->g_timer.reg.wstat |= G_WSTAT_COMP_L(index);
|
s->g_timer.reg.wstat |= G_WSTAT_COMP_L(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exynos4210_gfrc_tx_begin(&s->g_timer);
|
||||||
exynos4210_gfrc_restart(s);
|
exynos4210_gfrc_restart(s);
|
||||||
|
exynos4210_gfrc_tx_commit(&s->g_timer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case G_TCON:
|
case G_TCON:
|
||||||
|
@ -1178,6 +1216,8 @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
|
||||||
|
|
||||||
DPRINTF("global timer write to reg.g_tcon %llx\n", value);
|
DPRINTF("global timer write to reg.g_tcon %llx\n", value);
|
||||||
|
|
||||||
|
exynos4210_gfrc_tx_begin(&s->g_timer);
|
||||||
|
|
||||||
/* Start FRC if transition from disabled to enabled */
|
/* Start FRC if transition from disabled to enabled */
|
||||||
if ((value & G_TCON_TIMER_ENABLE) > (old_val &
|
if ((value & G_TCON_TIMER_ENABLE) > (old_val &
|
||||||
G_TCON_TIMER_ENABLE)) {
|
G_TCON_TIMER_ENABLE)) {
|
||||||
|
@ -1195,6 +1235,8 @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
|
||||||
exynos4210_gfrc_restart(s);
|
exynos4210_gfrc_restart(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exynos4210_gfrc_tx_commit(&s->g_timer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case G_INT_CSTAT:
|
case G_INT_CSTAT:
|
||||||
|
@ -1428,8 +1470,8 @@ static void exynos4210_mct_init(Object *obj)
|
||||||
QEMUBH *bh[2];
|
QEMUBH *bh[2];
|
||||||
|
|
||||||
/* Global timer */
|
/* Global timer */
|
||||||
bh[0] = qemu_bh_new(exynos4210_gfrc_event, s);
|
s->g_timer.ptimer_frc = ptimer_init(exynos4210_gfrc_event, s,
|
||||||
s->g_timer.ptimer_frc = ptimer_init_with_bh(bh[0], PTIMER_POLICY_DEFAULT);
|
PTIMER_POLICY_DEFAULT);
|
||||||
memset(&s->g_timer.reg, 0, sizeof(struct gregs));
|
memset(&s->g_timer.reg, 0, sizeof(struct gregs));
|
||||||
|
|
||||||
/* Local timers */
|
/* Local timers */
|
||||||
|
|
Loading…
Reference in a new issue