From ec28f31138bd0becb9d199c51369b8cba2951ab7 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 19 Sep 2017 09:12:02 +0200 Subject: bsp/qoriq: Add decrementer clock driver Update #3085. --- .../lib/libbsp/powerpc/qoriq/clock/clock-config.c | 51 +++++++++++++++++++--- c/src/lib/libbsp/powerpc/qoriq/include/bsp.h | 6 +++ c/src/lib/libbsp/powerpc/qoriq/irq/irq.c | 5 +++ c/src/lib/libbsp/powerpc/qoriq/start/start.S | 8 ++++ c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c | 7 ++- 5 files changed, 69 insertions(+), 8 deletions(-) (limited to 'c') diff --git a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c index ca61d255d3..82d8b8c57f 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c +++ b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2011, 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2011, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -31,6 +31,45 @@ /* This is defined in clockdrv_shell.h */ static rtems_isr Clock_isr(void *arg); +static struct timecounter qoriq_clock_tc; + +#ifdef QORIQ_IS_HYPERVISOR_GUEST + +#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR + +void qoriq_decrementer_dispatch(void) +{ + PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_TSR, BOOKE_TSR_DIS); + Clock_isr(NULL); +} + +static uint32_t qoriq_clock_get_timecount(struct timecounter *tc) +{ + return ppc_alternate_time_base(); +} + +static void qoriq_clock_initialize(void) +{ + uint64_t frequency = bsp_time_base_frequency; + uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); + uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000); + + PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1); + PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( + BOOKE_TCR, + BOOKE_TCR_DIE | BOOKE_TCR_ARE + ); + ppc_set_decrementer_register(interval - 1); + + qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount; + qoriq_clock_tc.tc_counter_mask = 0xffffffff; + qoriq_clock_tc.tc_frequency = qoriq_clock_frequency; + qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&qoriq_clock_tc); +} + +#else /* !QORIQ_IS_HYPERVISOR_GUEST */ + static volatile qoriq_pic_global_timer *const qoriq_clock = #if QORIQ_CLOCK_TIMER < 4 &qoriq.pic.gta [QORIQ_CLOCK_TIMER]; @@ -47,8 +86,6 @@ static volatile qoriq_pic_global_timer *const qoriq_timecounter = #define CLOCK_INTERRUPT (QORIQ_IRQ_GT_BASE + QORIQ_CLOCK_TIMER) -static struct timecounter qoriq_clock_tc; - static void qoriq_clock_handler_install(void) { rtems_status_code sc = RTEMS_SUCCESSFUL; @@ -123,9 +160,6 @@ static void qoriq_clock_cleanup(void) } } -#define Clock_driver_support_initialize_hardware() \ - qoriq_clock_initialize() - #define Clock_driver_support_install_isr(clock_isr) \ qoriq_clock_handler_install() @@ -135,5 +169,10 @@ static void qoriq_clock_cleanup(void) #define Clock_driver_support_shutdown_hardware() \ qoriq_clock_cleanup() +#endif /* QORIQ_IS_HYPERVISOR_GUEST */ + +#define Clock_driver_support_initialize_hardware() \ + qoriq_clock_initialize() + /* Include shared source clock driver code */ #include "../../../shared/clockdrv_shell.h" diff --git a/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h b/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h index 049790529b..d7e9e95b3f 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h +++ b/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h @@ -113,6 +113,12 @@ void qoriq_restart_secondary_processor( void qoriq_initialize_exceptions(void *interrupt_stack_begin); +void qoriq_decrementer_dispatch(void); + +extern uint32_t bsp_time_base_frequency; + +extern uint32_t qoriq_clock_frequency; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c index 39031c2f86..92d918fd4c 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c +++ b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c @@ -89,6 +89,11 @@ void bsp_interrupt_dispatch(uintptr_t exception_number) { unsigned int vector; + if (exception_number == 10) { + qoriq_decrementer_dispatch(); + return; + } + ev_int_iack(0, &vector); if (vector != SPURIOUS) { diff --git a/c/src/lib/libbsp/powerpc/qoriq/start/start.S b/c/src/lib/libbsp/powerpc/qoriq/start/start.S index 11c326df55..100173c3fa 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/start/start.S +++ b/c/src/lib/libbsp/powerpc/qoriq/start/start.S @@ -425,10 +425,18 @@ bsp_exc_vector_base: START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* Decrementer */ +#ifdef QORIQ_IS_HYPERVISOR_GUEST + PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1) +#else PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) +#endif PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 10 +#ifdef QORIQ_IS_HYPERVISOR_GUEST + b ppc_exc_interrupt +#else b ppc_exc_fatal_normal +#endif START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Fixed-interval timer interrupt */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c index 22eb678f59..72746ba21f 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c @@ -48,7 +48,9 @@ qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT]; unsigned int BSP_bus_frequency; /* Configuration parameter for clock driver, ... */ -uint32_t bsp_clicks_per_usec; +uint32_t bsp_time_base_frequency; + +uint32_t qoriq_clock_frequency; void BSP_panic(char *s) { @@ -97,13 +99,14 @@ static void initialize_frequency_parameters(void) if (val_fdt == NULL || len != 4) { bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY); } - bsp_clicks_per_usec = fdt32_to_cpu(*val_fdt) / 1000000; + bsp_time_base_frequency = fdt32_to_cpu(*val_fdt); #ifdef __PPC_CPU_E6500__ val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len); if (val_fdt == NULL || len != 4) { bsp_fatal(QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY); } + qoriq_clock_frequency = fdt32_to_cpu(*val_fdt); #endif rtems_counter_initialize_converter(fdt32_to_cpu(*val_fdt)); } -- cgit v1.2.3