forked from Imagelibrary/rtems
bsps: Move arm-a9mpcore-clock-config.c to bsps
This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
@@ -74,7 +74,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termio
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/altera-cyclone-v/console/console-config.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-a9mpcore.c
|
||||
|
||||
# I2C
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/altera-cyclone-v/i2c/i2cdrv.c
|
||||
|
||||
@@ -69,7 +69,7 @@ librtemsbsp_a_SOURCES += ../shared/arm-pl050.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/realview-pbx-a9/console/console-config.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-a9mpcore.c
|
||||
|
||||
# Cache
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/cache/cache-cp15.c
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/irq-generic.h>
|
||||
#include <bsp/arm-a9mpcore-regs.h>
|
||||
#include <bsp/arm-a9mpcore-clock.h>
|
||||
#include <rtems/timecounter.h>
|
||||
#include <rtems/score/smpimpl.h>
|
||||
|
||||
#define A9MPCORE_GT ((volatile a9mpcore_gt *) BSP_ARM_A9MPCORE_GT_BASE)
|
||||
|
||||
static struct timecounter a9mpcore_tc;
|
||||
|
||||
/* This is defined in dev/clock/clockimpl.h */
|
||||
void Clock_isr(rtems_irq_hdl_param arg);
|
||||
|
||||
__attribute__ ((weak)) uint32_t a9mpcore_clock_periphclk(void)
|
||||
{
|
||||
/* default to the BSP option. */
|
||||
return BSP_ARM_A9MPCORE_PERIPHCLK;
|
||||
}
|
||||
|
||||
static void a9mpcore_clock_at_tick(void)
|
||||
{
|
||||
volatile a9mpcore_gt *gt = A9MPCORE_GT;
|
||||
|
||||
gt->irqst = A9MPCORE_GT_IRQST_EFLG;
|
||||
}
|
||||
|
||||
static void a9mpcore_clock_handler_install(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_interrupt_handler_install(
|
||||
A9MPCORE_IRQ_GT,
|
||||
"Clock",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
(rtems_interrupt_handler) Clock_isr,
|
||||
NULL
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
bsp_fatal(BSP_ARM_A9MPCORE_FATAL_CLOCK_IRQ_INSTALL);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t a9mpcore_clock_get_counter(volatile a9mpcore_gt *gt)
|
||||
{
|
||||
uint32_t cl;
|
||||
uint32_t cu1;
|
||||
uint32_t cu2;
|
||||
|
||||
do {
|
||||
cu1 = gt->cntrupper;
|
||||
cl = gt->cntrlower;
|
||||
cu2 = gt->cntrupper;
|
||||
} while (cu1 != cu2);
|
||||
|
||||
return ((uint64_t) cu2 << 32) | cl;
|
||||
}
|
||||
|
||||
static uint32_t a9mpcore_clock_get_timecount(struct timecounter *tc)
|
||||
{
|
||||
volatile a9mpcore_gt *gt = A9MPCORE_GT;
|
||||
|
||||
return gt->cntrlower;
|
||||
}
|
||||
|
||||
static void a9mpcore_clock_gt_init(
|
||||
volatile a9mpcore_gt *gt,
|
||||
uint64_t cmpval,
|
||||
uint32_t interval
|
||||
)
|
||||
{
|
||||
gt->cmpvallower = (uint32_t) cmpval;
|
||||
gt->cmpvalupper = (uint32_t) (cmpval >> 32);
|
||||
gt->autoinc = interval;
|
||||
gt->ctrl = A9MPCORE_GT_CTRL_AUTOINC_EN
|
||||
| A9MPCORE_GT_CTRL_IRQ_EN
|
||||
| A9MPCORE_GT_CTRL_COMP_EN
|
||||
| A9MPCORE_GT_CTRL_TMR_EN;
|
||||
}
|
||||
|
||||
#if defined(RTEMS_SMP) && !defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
|
||||
typedef struct {
|
||||
uint64_t cmpval;
|
||||
uint32_t interval;
|
||||
} a9mpcore_clock_init_data;
|
||||
|
||||
static void a9mpcore_clock_secondary_action(void *arg)
|
||||
{
|
||||
volatile a9mpcore_gt *gt = A9MPCORE_GT;
|
||||
a9mpcore_clock_init_data *init_data = arg;
|
||||
|
||||
a9mpcore_clock_gt_init(gt, init_data->cmpval, init_data->interval);
|
||||
bsp_interrupt_vector_enable(A9MPCORE_IRQ_GT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void a9mpcore_clock_secondary_initialization(
|
||||
volatile a9mpcore_gt *gt,
|
||||
uint64_t cmpval,
|
||||
uint32_t interval
|
||||
)
|
||||
{
|
||||
#if defined(RTEMS_SMP) && !defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
|
||||
a9mpcore_clock_init_data init_data = {
|
||||
.cmpval = cmpval,
|
||||
.interval = interval
|
||||
};
|
||||
|
||||
_SMP_Before_multitasking_action_broadcast(
|
||||
a9mpcore_clock_secondary_action,
|
||||
&init_data
|
||||
);
|
||||
|
||||
if (cmpval - a9mpcore_clock_get_counter(gt) >= interval) {
|
||||
bsp_fatal(BSP_ARM_A9MPCORE_FATAL_CLOCK_SMP_INIT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void a9mpcore_clock_initialize(void)
|
||||
{
|
||||
volatile a9mpcore_gt *gt = A9MPCORE_GT;
|
||||
uint64_t periphclk = a9mpcore_clock_periphclk();
|
||||
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
||||
uint32_t interval = (uint32_t) ((periphclk * us_per_tick) / 1000000);
|
||||
uint64_t cmpval;
|
||||
|
||||
gt->ctrl &= A9MPCORE_GT_CTRL_TMR_EN;
|
||||
gt->irqst = A9MPCORE_GT_IRQST_EFLG;
|
||||
|
||||
cmpval = a9mpcore_clock_get_counter(gt);
|
||||
cmpval += interval;
|
||||
|
||||
a9mpcore_clock_gt_init(gt, cmpval, interval);
|
||||
a9mpcore_clock_secondary_initialization(gt, cmpval, interval);
|
||||
|
||||
a9mpcore_tc.tc_get_timecount = a9mpcore_clock_get_timecount;
|
||||
a9mpcore_tc.tc_counter_mask = 0xffffffff;
|
||||
a9mpcore_tc.tc_frequency = periphclk;
|
||||
a9mpcore_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
|
||||
rtems_timecounter_install(&a9mpcore_tc);
|
||||
}
|
||||
|
||||
CPU_Counter_ticks _CPU_Counter_read(void)
|
||||
{
|
||||
volatile a9mpcore_gt *gt = A9MPCORE_GT;
|
||||
|
||||
return gt->cntrlower;
|
||||
}
|
||||
|
||||
static void a9mpcore_clock_cleanup_isr(void *arg)
|
||||
{
|
||||
volatile a9mpcore_gt *gt = A9MPCORE_GT;
|
||||
|
||||
(void) arg;
|
||||
|
||||
gt->ctrl &= A9MPCORE_GT_CTRL_TMR_EN;
|
||||
gt->irqst = A9MPCORE_GT_IRQST_EFLG;
|
||||
}
|
||||
|
||||
static void a9mpcore_clock_cleanup(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
/*
|
||||
* The relevant registers / bits of the global timer are banked and chances
|
||||
* are on an SPM system, that we are executing on the wrong CPU to reset
|
||||
* them. Thus we will have the actual cleanup done with the next clock tick.
|
||||
* The ISR will execute on the right CPU for the cleanup.
|
||||
*/
|
||||
sc = rtems_interrupt_handler_install(
|
||||
A9MPCORE_IRQ_GT,
|
||||
"Clock",
|
||||
RTEMS_INTERRUPT_REPLACE,
|
||||
a9mpcore_clock_cleanup_isr,
|
||||
NULL
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
bsp_fatal(BSP_ARM_A9MPCORE_FATAL_CLOCK_IRQ_REMOVE);
|
||||
}
|
||||
}
|
||||
|
||||
#define Clock_driver_support_at_tick() \
|
||||
a9mpcore_clock_at_tick()
|
||||
|
||||
#define Clock_driver_support_initialize_hardware() \
|
||||
a9mpcore_clock_initialize()
|
||||
|
||||
#define Clock_driver_support_install_isr(isr) \
|
||||
a9mpcore_clock_handler_install()
|
||||
|
||||
#define Clock_driver_support_shutdown_hardware() \
|
||||
a9mpcore_clock_cleanup()
|
||||
|
||||
/* Include shared source clock driver code */
|
||||
#include "../../shared/dev/clock/clockimpl.h"
|
||||
@@ -65,7 +65,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/debug-co
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/zynq-uart.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-a9mpcore.c
|
||||
|
||||
# I2C
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/i2c/cadence-i2c.c
|
||||
|
||||
Reference in New Issue
Block a user