Hi Simon, On Fri, May 25, 2018 at 4:42 AM, Simon Glass <s...@chromium.org> wrote: > Hi Mario, > > On 24 May 2018 at 02:42, Mario Six <mario....@gdsys.cc> wrote: >> Add a timer driver for the MPC83xx architecture. >> >> Signed-off-by: Mario Six <mario....@gdsys.cc> >> >> --- >> >> v2 -> v3: >> * Got rid of the static variables >> * Added driver files to MAINTAINERS >> >> v1 -> v2: >> * Removed now-superfluous comments >> * Removed usage of uclass_{first,next}_device_compat >> * Switched to usage of new board uclass (instead of devinfo) >> >> --- >> MAINTAINERS | 1 + >> arch/powerpc/cpu/mpc83xx/cpu.c | 4 +- >> arch/powerpc/lib/Makefile | 4 + >> arch/powerpc/lib/interrupts.c | 5 +- >> drivers/timer/Kconfig | 7 ++ >> drivers/timer/Makefile | 1 + >> drivers/timer/mpc83xx_timer.c | 182 >> +++++++++++++++++++++++++++++++++++++++++ >> 7 files changed, 201 insertions(+), 3 deletions(-) >> create mode 100644 drivers/timer/mpc83xx_timer.c >> > [..] > >> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile >> index ee2fcb1fa71..75360d81de3 100644 >> --- a/drivers/timer/Makefile >> +++ b/drivers/timer/Makefile >> @@ -16,3 +16,4 @@ obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o >> obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o >> obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o >> obj-$(CONFIG_STM32_TIMER) += stm32_timer.o >> +obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o >> diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c >> new file mode 100644 >> index 00000000000..148fb2550ca >> --- /dev/null >> +++ b/drivers/timer/mpc83xx_timer.c >> @@ -0,0 +1,182 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * (C) Copyright 2018 >> + * Mario Six, Guntermann & Drunck GmbH, mario....@gdsys.cc >> + */ >> + >> +#include <common.h> >> +#include <dm.h> >> +#include <clk.h> >> +#include <timer.h> >> +#include <watchdog.h> >> +#include <board.h> >> + >> +DECLARE_GLOBAL_DATA_PTR; >> + >> +struct mpc83xx_timer_priv { >> + uint decrementer_count; /* count value for 1e6/HZ microseconds */ >> + ulong timestamp; >> +}; >> + >> +static inline unsigned long get_dec(void) >> +{ >> + unsigned long val; >> + >> + asm volatile ("mfdec %0" : "=r" (val) : ); >> + >> + return val; >> +} >> + >> +static inline void set_dec(unsigned long val) >> +{ >> + if (val) >> + asm volatile ("mtdec %0"::"r" (val)); >> +} >> + >> +/* TODO(mario....@gdsys.cc): This should really be done by timer_init, and >> the >> + * interrupt init should go into a interrupt driver. >> + */ >> +int interrupt_init(void) >> +{ >> + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; >> + struct udevice *csb; >> + struct udevice *board; >> + struct udevice *timer = gd->timer; >> + struct mpc83xx_timer_priv *timer_priv = dev_get_priv(timer); >> + struct clk clock; >> + int ret; >> + >> + if (get_board(&board)) { >> + debug("%s: board device could not be fetched.\n", __func__); >> + return -ENOENT; >> + } >> + >> + ret = uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, >> + "csb", &csb); >> + if (ret) { >> + debug("%s: Could not retrieve CSB device (error: %d)", >> + __func__, ret); >> + return ret; >> + } >> + >> + ret = clk_get_by_index(csb, 0, &clock); >> + if (ret) { >> + debug("%s: Could not retrieve clock (error: %d)", >> + __func__, ret); >> + return ret; >> + } >> + >> + timer_priv->decrementer_count = (clk_get_rate(&clock) / 4) >> + / CONFIG_SYS_HZ; >> + /* Enable e300 time base */ >> + setbits_be32(&immr->sysconf.spcr, 0x00400000); >> + >> + set_dec(timer_priv->decrementer_count); >> + >> + set_msr(get_msr() | MSR_EE); >> + >> + return 0; >> +} >> + >> +void timer_interrupt(struct pt_regs *regs) >> +{ >> + struct udevice *timer = gd->timer; >> + struct mpc83xx_timer_priv *priv = dev_get_priv(timer); >> + >> + /* Restore Decrementer Count */ >> + set_dec(priv->decrementer_count); >> + >> + priv->timestamp++; >> + >> +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) >> + if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) >> + WATCHDOG_RESET(); >> +#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ >> + >> +#ifdef CONFIG_LED_STATUS >> + status_led_tick(priv->timestamp); >> +#endif /* CONFIG_LED_STATUS */ >> + >> +#ifdef CONFIG_SHOW_ACTIVITY >> + board_show_activity(priv->timestamp); >> +#endif /* CONFIG_SHOW_ACTIVITY */ >> +} >> + >> +ulong get_timer(ulong base) > > How come you are defining that? The standard one should work, and it > calls get_ticks() which should call your driver. >
I see. I wasn't aware of the fact that the default timer driver infrastructure already does that, so I copied the old get_timer implementation over to this driver. I'll use the default function in v4. > Regards, > Simon Best regards, Mario _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot