bsp/qoriq: Add decrementer clock driver

Update #3085.
This commit is contained in:
Sebastian Huber
2017-09-19 09:12:02 +02:00
parent fd70e20621
commit ec28f31138
5 changed files with 69 additions and 8 deletions

View File

@@ -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"

View File

@@ -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 */

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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));
}