Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:38

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsARMTMS570
0007  *
0008  * @brief This source file contains the Clock Driver implementation.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2024 embedded brains GmbH & Co. KG
0013  * Copyright (C) 2014 Premysl Houdek <kom541000@gmail.com>
0014  *
0015  * Google Summer of Code 2014 at
0016  * Czech Technical University in Prague
0017  * Zikova 1903/4
0018  * 166 36 Praha 6
0019  * Czech Republic
0020  *
0021  * Redistribution and use in source and binary forms, with or without
0022  * modification, are permitted provided that the following conditions
0023  * are met:
0024  * 1. Redistributions of source code must retain the above copyright
0025  *    notice, this list of conditions and the following disclaimer.
0026  * 2. Redistributions in binary form must reproduce the above copyright
0027  *    notice, this list of conditions and the following disclaimer in the
0028  *    documentation and/or other materials provided with the distribution.
0029  *
0030  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0031  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0032  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0033  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0034  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0035  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0036  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0038  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0039  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0040  * POSSIBILITY OF SUCH DAMAGE.
0041  */
0042 
0043 #include <bsp.h>
0044 #include <bsp/fatal.h>
0045 #include <bsp/irq.h>
0046 #include <bsp/tms570.h>
0047 #include <rtems/counter.h>
0048 #include <rtems/sysinit.h>
0049 #include <rtems/timecounter.h>
0050 
0051 static struct timecounter tms570_rti_tc;
0052 
0053 uint32_t _CPU_Counter_frequency(void)
0054 {
0055   return TMS570_RTICLK_HZ / 2;
0056 }
0057 
0058 CPU_Counter_ticks _CPU_Counter_read(void)
0059 {
0060   return TMS570_RTI.CNT[0].FRCx;
0061 }
0062 
0063 static void tms570_rti_initialize( void )
0064 {
0065   /* Initialize module */
0066   TMS570_RTI.GCTRL = 0;
0067   TMS570_RTI.CAPCTRL = 0;
0068   TMS570_RTI.COMPCTRL = 0;
0069   TMS570_RTI.TBCTRL = TMS570_RTI_TBCTRL_INC;
0070   TMS570_RTI.INTCLRENABLE = 0x05050505;
0071 
0072   /* Disable interrupts */
0073   TMS570_RTI.CLEARINTENA = TMS570_RTI_CLEARINTENA_CLEAROVL1INT |
0074                            TMS570_RTI_CLEARINTENA_CLEAROVL0INT |
0075                            TMS570_RTI_CLEARINTENA_CLEARTBINT |
0076                            TMS570_RTI_CLEARINTENA_CLEARDMA3 |
0077                            TMS570_RTI_CLEARINTENA_CLEARDMA2 |
0078                            TMS570_RTI_CLEARINTENA_CLEARDMA1 |
0079                            TMS570_RTI_CLEARINTENA_CLEARDMA0 |
0080                            TMS570_RTI_CLEARINTENA_CLEARINT3 |
0081                            TMS570_RTI_CLEARINTENA_CLEARINT2 |
0082                            TMS570_RTI_CLEARINTENA_CLEARINT1 |
0083                            TMS570_RTI_CLEARINTENA_CLEARINT0;
0084 
0085   /* Initialize counter 0 */
0086   TMS570_RTI.CNT[0].CPUCx = 1;
0087   TMS570_RTI.CNT[0].UCx = 0;
0088   TMS570_RTI.CNT[0].FRCx = 0;
0089 
0090   /* Enable counter 0 */
0091   TMS570_RTI.GCTRL = TMS570_RTI_GCTRL_CNT0EN;
0092 }
0093 
0094 RTEMS_SYSINIT_ITEM(
0095   tms570_rti_initialize,
0096   RTEMS_SYSINIT_CPU_COUNTER,
0097   RTEMS_SYSINIT_ORDER_MIDDLE
0098 );
0099 
0100 static uint32_t tms570_rti_get_timecount(struct timecounter *tc)
0101 {
0102   return TMS570_RTI.CNT[0].FRCx;
0103 }
0104 
0105 static void tms570_clock_driver_support_initialize_hardware( void )
0106 {
0107 
0108   uint64_t usec_per_tick;
0109   uint32_t tc_frequency;
0110   uint32_t tc_increments_per_tick;
0111   struct timecounter *tc;
0112 
0113   usec_per_tick = rtems_configuration_get_microseconds_per_tick();
0114   tc_frequency = TMS570_RTICLK_HZ / 2;
0115   tc_increments_per_tick = (usec_per_tick * tc_frequency + 500000) / 1000000;
0116 
0117   /* Initialize compare 0 */
0118   TMS570_RTI.CMP[0].UDCPx = tc_increments_per_tick;
0119   TMS570_RTI.CMP[0].COMPx = TMS570_RTI.CNT[0].FRCx + tc_increments_per_tick;
0120 
0121   /* Clear interrupts */
0122   TMS570_RTI.INTFLAG = TMS570_RTI_INTFLAG_OVL1INT |
0123                        TMS570_RTI_INTFLAG_OVL0INT |
0124                        TMS570_RTI_INTFLAG_TBINT |
0125                        TMS570_RTI_INTFLAG_INT3 |
0126                        TMS570_RTI_INTFLAG_INT2 |
0127                        TMS570_RTI_INTFLAG_INT1 |
0128                        TMS570_RTI_INTFLAG_INT0;
0129 
0130   /* Enable interrupts for counter 0 */
0131   TMS570_RTI.SETINTENA = TMS570_RTI_SETINTENA_SETINT0;
0132 
0133   tc = &tms570_rti_tc;
0134   tc->tc_get_timecount = tms570_rti_get_timecount;
0135   tc->tc_counter_mask = 0xffffffff;
0136   tc->tc_frequency = tc_frequency;
0137   tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
0138   rtems_timecounter_install(tc);
0139 }
0140 
0141 static void tms570_clock_driver_support_at_tick(volatile tms570_rti_t *rti)
0142 {
0143   rti->INTFLAG = TMS570_RTI_INTFLAG_INT0;
0144 }
0145 
0146 static void tms570_clock_driver_support_install_isr(
0147   rtems_interrupt_handler handler
0148 )
0149 {
0150   rtems_status_code sc;
0151 
0152   sc = rtems_interrupt_handler_install(
0153     TMS570_IRQ_TIMER_0,
0154     "Clock",
0155     RTEMS_INTERRUPT_UNIQUE,
0156     handler,
0157     RTEMS_DEVOLATILE(tms570_rti_t *, &TMS570_RTI)
0158   );
0159   if (sc != RTEMS_SUCCESSFUL) {
0160     bsp_fatal(TMS570_FATAL_RTI_IRQ_INSTALL);
0161   }
0162 }
0163 
0164 #define Clock_driver_support_initialize_hardware() \
0165   tms570_clock_driver_support_initialize_hardware()
0166 #define Clock_driver_support_at_tick(arg) \
0167   tms570_clock_driver_support_at_tick(arg)
0168 #define Clock_driver_support_install_isr(handler) \
0169   tms570_clock_driver_support_install_isr(handler)
0170 
0171 #include "../../../shared/dev/clock/clockimpl.h"