File indexing completed on 2025-05-11 08:23:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp.h>
0037 #include <bsp/fatal.h>
0038 #include <bsp/timer.h>
0039
0040 #include <rtems.h>
0041 #include <rtems/irq-extension.h>
0042 #include <rtems/timecounter.h>
0043
0044 static rtems_timecounter_simple mblaze_tc;
0045 static volatile Microblaze_Timer *mblaze_timer;
0046
0047 static uint32_t microblaze_tc_get( rtems_timecounter_simple *tc )
0048 {
0049 return mblaze_timer->tcr0;
0050 }
0051
0052 static bool microblaze_tc_is_pending( rtems_timecounter_simple *tc )
0053 {
0054 return ( mblaze_timer->tcsr0 & MICROBLAZE_TIMER_TCSR0_T0INT ) != 0;
0055 }
0056
0057 static uint32_t microblaze_tc_get_timecount( struct timecounter *tc )
0058 {
0059 return rtems_timecounter_simple_downcounter_get(
0060 tc,
0061 microblaze_tc_get,
0062 microblaze_tc_is_pending
0063 );
0064 }
0065
0066 static void microblaze_clock_initialize( void )
0067 {
0068 mblaze_timer = (volatile Microblaze_Timer *) try_get_prop_from_device_tree(
0069 "xlnx,xps-timer-1.00.a",
0070 "reg",
0071 BSP_MICROBLAZE_FPGA_TIMER_BASE
0072 );
0073
0074
0075 mblaze_timer->tlr0 = 0;
0076
0077 mblaze_timer->tcsr0 = MICROBLAZE_TIMER_TCSR0_T0INT | MICROBLAZE_TIMER_TCSR0_LOAD0;
0078
0079 mblaze_timer->tcsr0 = 0;
0080
0081
0082
0083
0084 mblaze_timer->tcsr0 = MICROBLAZE_TIMER_TCSR0_ARHT0 | MICROBLAZE_TIMER_TCSR0_ENIT0 |
0085 MICROBLAZE_TIMER_TCSR0_GENT0 | MICROBLAZE_TIMER_TCSR0_UDT0;
0086
0087 uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
0088 uint32_t counter_frequency_in_hz = try_get_prop_from_device_tree(
0089 "xlnx,xps-timer-1.00.a",
0090 "clock-frequency",
0091 BSP_MICROBLAZE_FPGA_TIMER_FREQUENCY
0092 );
0093 uint32_t counter_ticks_per_clock_tick =
0094 ( counter_frequency_in_hz * us_per_tick ) / 1000000;
0095
0096
0097 mblaze_timer->tlr0 = counter_ticks_per_clock_tick;
0098 uint32_t control_status_reg = mblaze_timer->tcsr0;
0099
0100 mblaze_timer->tcsr0 = MICROBLAZE_TIMER_TCSR0_LOAD0;
0101
0102 mblaze_timer->tcsr0 = control_status_reg | MICROBLAZE_TIMER_TCSR0_ENT0;
0103
0104 rtems_timecounter_simple_install(
0105 &mblaze_tc,
0106 counter_frequency_in_hz,
0107 counter_ticks_per_clock_tick,
0108 microblaze_tc_get_timecount
0109 );
0110 }
0111
0112 static void microblaze_clock_at_tick( rtems_timecounter_simple *tc )
0113 {
0114 if ( ( mblaze_timer->tcsr0 & MICROBLAZE_TIMER_TCSR0_T0INT ) == 0 ) {
0115 return;
0116 }
0117
0118 mblaze_timer->tcsr0 |= MICROBLAZE_TIMER_TCSR0_T0INT;
0119 }
0120
0121 static void microblaze_tc_tick( rtems_timecounter_simple *tc )
0122 {
0123 rtems_timecounter_simple_downcounter_tick(
0124 tc,
0125 microblaze_tc_get,
0126 microblaze_clock_at_tick
0127 );
0128 }
0129
0130 static void microblaze_clock_handler_install( rtems_interrupt_handler isr )
0131 {
0132 rtems_status_code sc = RTEMS_SUCCESSFUL;
0133
0134 uint32_t clock_irq_num = try_get_prop_from_device_tree(
0135 "xlnx,xps-timer-1.00.a",
0136 "interrupts",
0137 0
0138 );
0139
0140 sc = rtems_interrupt_handler_install(
0141 clock_irq_num,
0142 "Clock",
0143 RTEMS_INTERRUPT_UNIQUE,
0144 isr,
0145 &mblaze_tc
0146 );
0147
0148 if ( sc != RTEMS_SUCCESSFUL ) {
0149 bsp_fatal( MICROBLAZE_FATAL_CLOCK_IRQ_INSTALL );
0150 }
0151 }
0152
0153 #define Clock_driver_support_initialize_hardware() microblaze_clock_initialize()
0154 #define Clock_driver_support_install_isr( isr ) \
0155 microblaze_clock_handler_install( isr )
0156 #define Clock_driver_timecounter_tick(arg) microblaze_tc_tick(arg)
0157
0158
0159 #include "../../shared/dev/clock/clockimpl.h"