source: rtems/bsps/arm/raspberrypi/clock/clockdrv.c

Last change on this file was 6136e28b, checked in by Sebastian Huber <sebastian.huber@…>, on 01/23/23 at 14:26:10

clockdrv: Add clock driver implementation group

Use standard wording in Clock Driver related files.

Update #3706.

  • Property mode set to 100644
File size: 2.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSDriverClockImpl
5 *
6 * @brief This source file contains the implementation of the BCM2835 Clock
7 *   Driver.
8 */
9
10/*
11 * Copyright (c) 2013 Alan Cudmore
12 * Copyright (c) 2016 Pavel Pisa
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *
17 *  http://www.rtems.org/license/LICENSE
18 *
19*/
20
21#include <rtems.h>
22#include <bsp.h>
23#include <bsp/irq.h>
24#include <bsp/irq-generic.h>
25#include <bsp/raspberrypi.h>
26#include <rtems/timecounter.h>
27
28/* This is defined in ../../../shared/dev/clock/clockimpl.h */
29void Clock_isr(rtems_irq_hdl_param arg);
30
31static struct timecounter raspberrypi_tc;
32
33static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc)
34{
35  return BCM2835_REG(BCM2835_GPU_TIMER_CLO);
36}
37
38static void raspberrypi_clock_at_tick(void)
39{
40  uint32_t act_val;
41  uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3);
42  next_cmp += rtems_configuration_get_microseconds_per_tick();
43  BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
44  act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
45
46  /*
47   * Clear interrupt only if there is time left to the next tick.
48   * If time of the next tick has already passed then interrupt
49   * request stays active and fires immediately after current tick
50   * processing is finished.
51   */
52  if ((int32_t)(next_cmp - act_val) > 0)
53    BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
54}
55
56static void raspberrypi_clock_handler_install_isr(
57  rtems_isr_entry clock_isr
58)
59{
60  rtems_status_code sc = RTEMS_SUCCESSFUL;
61
62  if (clock_isr != NULL) {
63    sc = rtems_interrupt_handler_install(
64      BCM2835_IRQ_ID_GPU_TIMER_M3,
65      "Clock",
66      RTEMS_INTERRUPT_UNIQUE,
67      (rtems_interrupt_handler) clock_isr,
68      NULL
69    );
70  } else {
71    /* Remove interrupt handler */
72    sc = rtems_interrupt_handler_remove(
73      BCM2835_IRQ_ID_GPU_TIMER_M3,
74      (rtems_interrupt_handler) Clock_isr,
75      NULL
76    );
77  }
78  if ( sc != RTEMS_SUCCESSFUL ) {
79    rtems_fatal_error_occurred(0xdeadbeef);
80  }
81}
82
83static void raspberrypi_clock_initialize_hardware(void)
84{
85  uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
86  next_cmp += rtems_configuration_get_microseconds_per_tick();
87  BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
88  BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
89
90  raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount;
91  raspberrypi_tc.tc_counter_mask = 0xffffffff;
92  raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */
93  raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
94  rtems_timecounter_install(&raspberrypi_tc);
95}
96
97#define Clock_driver_support_at_tick() raspberrypi_clock_at_tick()
98
99#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware()
100
101#define Clock_driver_support_install_isr(clock_isr) \
102  raspberrypi_clock_handler_install_isr(clock_isr)
103
104#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1
105
106#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.