From 7632906fc290b652416ab59eb5fb49356c064ed6 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 19 Apr 2018 06:35:52 +0200 Subject: bsps: Move clock drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- bsps/m68k/mcf5225x/clock/clock.c | 106 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 bsps/m68k/mcf5225x/clock/clock.c (limited to 'bsps/m68k/mcf5225x/clock/clock.c') diff --git a/bsps/m68k/mcf5225x/clock/clock.c b/bsps/m68k/mcf5225x/clock/clock.c new file mode 100644 index 0000000000..b01c37aef7 --- /dev/null +++ b/bsps/m68k/mcf5225x/clock/clock.c @@ -0,0 +1,106 @@ +/* + * Use the last periodic interval timer (PIT2) as the system clock. + */ + +#include +#include +#include + +/* + * Use INTC0 base + */ +#define CLOCK_VECTOR (64+56) + +static rtems_timecounter_simple mcf5225x_tc; + +static uint32_t mcf5225x_tc_get(rtems_timecounter_simple *tc) +{ + return MCF_PIT1_PCNTR; +} + +static bool mcf5225x_tc_is_pending(rtems_timecounter_simple *tc) +{ + return (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) != 0; +} + +static uint32_t mcf5225x_tc_get_timecount(struct timecounter *tc) +{ + return rtems_timecounter_simple_downcounter_get( + tc, + mcf5225x_tc_get, + mcf5225x_tc_is_pending + ); +} + +static void mcf5225x_tc_at_tick(rtems_timecounter_simple *tc) +{ + MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; +} + +static void mcf5225x_tc_tick(void) +{ + rtems_timecounter_simple_downcounter_tick( + &mcf5225x_tc, + mcf5225x_tc_get, + mcf5225x_tc_at_tick + ); +} + +/* + * Attach clock interrupt handler + */ +#define Clock_driver_support_install_isr( _new ) \ + set_vector(_new, CLOCK_VECTOR, 1) + +/* + * Turn off the clock + */ +#define Clock_driver_support_shutdown_hardware() \ + do { \ + MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; \ + } while (0) + +/* + * Set up the clock hardware + * + * We need to have 1 interrupt every BSP_rtems_configuration_get_microseconds_per_tick() + */ +static void Clock_driver_support_initialize_hardware(void) +{ + int level; + uint32_t pmr; + uint32_t preScaleCode = 0; + uint32_t clk = bsp_get_CPU_clock_speed() >> 1; + uint32_t tps = 1000000 / rtems_configuration_get_microseconds_per_tick(); + + while (preScaleCode < 15) { + pmr = (clk >> preScaleCode) / tps; + if (pmr < (1 << 15)) + break; + preScaleCode++; + } + + MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) | + MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY); + rtems_interrupt_disable(level); + MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_MASK56; + MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; + rtems_interrupt_enable(level); + + MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) | + MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD; + MCF_PIT1_PMR = pmr; + MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) | + MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN; + + rtems_timecounter_simple_install( + &mcf5225x_tc, + clk >> preScaleCode, + pmr, + mcf5225x_tc_get_timecount + ); +} + +#define Clock_driver_timecounter_tick() mcf5225x_tc_tick() + +#include "../../../shared/dev/clock/clockimpl.h" -- cgit v1.2.3