Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:04

0001 /**
0002  * @file
0003  *
0004  * @ingroup RTEMSDriverClockImpl
0005  *
0006  * @brief This source file contains the implementation of the BCM2835 Clock
0007  *   Driver.
0008  */
0009 
0010 /*
0011  * Copyright (c) 2013 Alan Cudmore
0012  * Copyright (c) 2016 Pavel Pisa
0013  *
0014  *  The license and distribution terms for this file may be
0015  *  found in the file LICENSE in this distribution or at
0016  *
0017  *  http://www.rtems.org/license/LICENSE
0018  *
0019 */
0020 
0021 #include <rtems.h>
0022 #include <bsp.h>
0023 #include <bsp/irq.h>
0024 #include <bsp/irq-generic.h>
0025 #include <bsp/raspberrypi.h>
0026 #include <rtems/timecounter.h>
0027 
0028 static struct timecounter raspberrypi_tc;
0029 
0030 static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc)
0031 {
0032   return BCM2835_REG(BCM2835_GPU_TIMER_CLO);
0033 }
0034 
0035 static void raspberrypi_clock_at_tick(void)
0036 {
0037   uint32_t act_val;
0038   uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3);
0039   next_cmp += rtems_configuration_get_microseconds_per_tick();
0040   BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
0041   act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
0042 
0043   /*
0044    * Clear interrupt only if there is time left to the next tick.
0045    * If time of the next tick has already passed then interrupt
0046    * request stays active and fires immediately after current tick
0047    * processing is finished.
0048    */
0049   if ((int32_t)(next_cmp - act_val) > 0)
0050     BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
0051 }
0052 
0053 static void raspberrypi_clock_handler_install_isr(
0054   rtems_interrupt_handler clock_isr
0055 )
0056 {
0057   rtems_status_code sc = RTEMS_SUCCESSFUL;
0058 
0059   sc = rtems_interrupt_handler_install(
0060     BCM2835_IRQ_ID_GPU_TIMER_M3,
0061     "Clock",
0062     RTEMS_INTERRUPT_UNIQUE,
0063     clock_isr,
0064     NULL
0065   );
0066   if ( sc != RTEMS_SUCCESSFUL ) {
0067     rtems_fatal_error_occurred(0xdeadbeef);
0068   }
0069 }
0070 
0071 static void raspberrypi_clock_initialize_hardware(void)
0072 {
0073   uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
0074   next_cmp += rtems_configuration_get_microseconds_per_tick();
0075   BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
0076   BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
0077 
0078   raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount;
0079   raspberrypi_tc.tc_counter_mask = 0xffffffff;
0080   raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */
0081   raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
0082   rtems_timecounter_install(&raspberrypi_tc);
0083 }
0084 
0085 #define Clock_driver_support_at_tick(arg) raspberrypi_clock_at_tick()
0086 
0087 #define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware()
0088 
0089 #define Clock_driver_support_install_isr(clock_isr) \
0090   raspberrypi_clock_handler_install_isr(clock_isr)
0091 
0092 #define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1
0093 
0094 #include "../../../shared/dev/clock/clockimpl.h"