summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-19 09:12:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-19 10:57:27 +0200
commitec28f31138bd0becb9d199c51369b8cba2951ab7 (patch)
tree7bbf2c9453674d98559ec1573cf7eaba5440bd11
parentfd70e20621e652f7bd6553ad4e0c39d6c5eccfdc (diff)
downloadrtems-ec28f31138bd0becb9d199c51369b8cba2951ab7.tar.bz2
bsp/qoriq: Add decrementer clock driver
Update #3085.
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c51
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/include/bsp.h6
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/irq/irq.c5
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/start/start.S8
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c7
5 files changed, 69 insertions, 8 deletions
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));
}