Make Marvell armv7 timer and wdt registers definitions common

Define timers registers for both SoCs and choose proper one during runtime
based on information from FDT.
In WDT driver there are different function for ArmadaXP and other ARMv5 SoCs.
In timer driver registers definitions are stored in resource_spec structure
and chosen during runtime.

Submitted by: Rafal Kozik <rk@semihalf.com>
Obtained from: Semihalf
Sponsored by: Stormshield
Differential Revision: https://reviews.freebsd.org/D14746
This commit is contained in:
Marcin Wojtas 2018-04-04 12:30:52 +00:00
parent 28cfdee769
commit 789bbd4d27
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332011
3 changed files with 44 additions and 28 deletions

View File

@ -253,7 +253,11 @@ mv_wdt_enable_armada_38x_xp_helper()
static void
mv_wdt_enable_armada_38x(void)
{
uint32_t val;
uint32_t val, irq_cause;
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER_WD_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
mv_wdt_enable_armada_38x_xp_helper();
@ -265,7 +269,10 @@ mv_wdt_enable_armada_38x(void)
static void
mv_wdt_enable_armada_xp(void)
{
uint32_t val;
uint32_t val, irq_cause;
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE_ARMADAXP);
irq_cause &= IRQ_TIMER_WD_CLR_ARMADAXP;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE_ARMADAXP, irq_cause);
mv_wdt_enable_armada_38x_xp_helper();

View File

@ -76,18 +76,16 @@
#define MSI_IRQ_NUM 32
#define IRQ_CPU_SELF 0x00000001
#if defined(SOC_MV_ARMADAXP)
#define BRIDGE_IRQ_CAUSE 0x68
#define IRQ_TIMER0 0x00000001
#define IRQ_TIMER1 0x00000002
#define IRQ_TIMER_WD 0x00000004
#else
#define BRIDGE_IRQ_CAUSE_ARMADAXP 0x68
#define IRQ_TIMER0_ARMADAXP 0x00000001
#define IRQ_TIMER1_ARMADAXP 0x00000002
#define IRQ_TIMER_WD_ARMADAXP 0x00000004
#define BRIDGE_IRQ_CAUSE 0x10
#define IRQ_CPU_SELF 0x00000001
#define IRQ_TIMER0 0x00000002
#define IRQ_TIMER1 0x00000004
#define IRQ_TIMER_WD 0x00000008
#endif
#define BRIDGE_IRQ_MASK 0x14
#define IRQ_CPU_MASK 0x00000001
@ -97,9 +95,11 @@
#define IRQ_CPU_SELF_CLR (~IRQ_CPU_SELF)
#define IRQ_TIMER0_CLR (~IRQ_TIMER0)
#define IRQ_TIMER1_CLR (~IRQ_TIMER1)
#define IRQ_TIMER_WD_CLR (~IRQ_TIMER_WD)
#define IRQ_TIMER0_CLR_ARMADAXP (~IRQ_TIMER0_ARMADAXP)
#define IRQ_TIMER_WD_CLR_ARMADAXP (~IRQ_TIMER_WD_ARMADAXP)
/*
* System reset
*/

View File

@ -73,6 +73,9 @@ struct mv_timer_config {
mv_watchdog_enable_t watchdog_enable;
mv_watchdog_disable_t watchdog_disable;
unsigned int clock_src;
uint32_t bridge_irq_cause;
uint32_t irq_timer0_clr;
uint32_t irq_timer_wd_clr;
};
struct mv_timer_softc {
@ -132,6 +135,9 @@ static struct mv_timer_config timer_armadaxp_config =
&mv_watchdog_enable_armadaxp,
&mv_watchdog_disable_armadaxp,
MV_CLOCK_SRC_ARMV7,
BRIDGE_IRQ_CAUSE_ARMADAXP,
IRQ_TIMER0_CLR_ARMADAXP,
IRQ_TIMER_WD_CLR_ARMADAXP,
};
static struct mv_timer_config timer_armv5_config =
{
@ -139,6 +145,9 @@ static struct mv_timer_config timer_armv5_config =
&mv_watchdog_enable_armv5,
&mv_watchdog_disable_armv5,
0,
BRIDGE_IRQ_CAUSE,
IRQ_TIMER0_CLR,
IRQ_TIMER_WD_CLR,
};
static struct ofw_compat_data mv_timer_soc_config[] = {
@ -228,10 +237,10 @@ mv_timer_attach(device_t dev)
mv_setup_timers();
if (sc->config->soc_family != MV_SOC_ARMADA_XP ) {
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER0_CLR;
irq_cause = read_cpu_ctrl(sc->config->bridge_irq_cause);
irq_cause &= sc->config->irq_timer0_clr;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
write_cpu_ctrl(sc->config->bridge_irq_cause, irq_cause);
irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
irq_mask |= IRQ_TIMER0_MASK;
irq_mask &= ~IRQ_TIMER1_MASK;
@ -263,9 +272,9 @@ mv_hardclock(void *arg)
struct mv_timer_softc *sc;
uint32_t irq_cause;
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER0_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
irq_cause = read_cpu_ctrl(timer_softc->config->bridge_irq_cause);
irq_cause &= timer_softc->config->irq_timer0_clr;
write_cpu_ctrl(timer_softc->config->bridge_irq_cause, irq_cause);
sc = (struct mv_timer_softc *)arg;
if (sc->et.et_active)
@ -381,9 +390,9 @@ mv_watchdog_enable_armv5(void)
{
uint32_t val, irq_cause, irq_mask;
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER_WD_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
irq_cause = read_cpu_ctrl(timer_softc->config->bridge_irq_cause);
irq_cause &= timer_softc->config->irq_timer_wd_clr;
write_cpu_ctrl(timer_softc->config->bridge_irq_cause, irq_cause);
irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
irq_mask |= IRQ_TIMER_WD_MASK;
@ -403,9 +412,9 @@ mv_watchdog_enable_armadaxp(void)
{
uint32_t irq_cause, val;
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER_WD_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
irq_cause = read_cpu_ctrl(timer_softc->config->bridge_irq_cause);
irq_cause &= timer_softc->config->irq_timer_wd_clr;
write_cpu_ctrl(timer_softc->config->bridge_irq_cause, irq_cause);
val = read_cpu_mp_clocks(WD_RSTOUTn_MASK);
val |= (WD_GLOBAL_MASK | WD_CPU0_MASK);
@ -437,9 +446,9 @@ mv_watchdog_disable_armv5(void)
irq_mask &= ~(IRQ_TIMER_WD_MASK);
write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask);
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER_WD_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
irq_cause = read_cpu_ctrl(timer_softc->config->bridge_irq_cause);
irq_cause &= timer_softc->config->irq_timer_wd_clr;
write_cpu_ctrl(timer_softc->config->bridge_irq_cause, irq_cause);
}
static void
@ -455,9 +464,9 @@ mv_watchdog_disable_armadaxp(void)
val |= RSTOUTn_MASK_WD;
write_cpu_misc(RSTOUTn_MASK_ARMV7, RSTOUTn_MASK_WD);
irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
irq_cause &= IRQ_TIMER_WD_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
irq_cause = read_cpu_ctrl(timer_softc->config->bridge_irq_cause);
irq_cause &= timer_softc->config->irq_timer_wd_clr;
write_cpu_ctrl(timer_softc->config->bridge_irq_cause, irq_cause);
val = mv_get_timer_control();
val &= ~(CPU_TIMER2_EN | CPU_TIMER2_AUTO);