File indexing completed on 2025-05-11 08:22:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <rtems.h>
0018 #include <rtems/timecounter.h>
0019 #include <bsp.h>
0020
0021 #include <libcpu/omap_timer.h>
0022
0023 static struct timecounter beagle_clock_tc;
0024
0025 static omap_timer_registers_t regs_v1 = {
0026 .TIDR = OMAP3_TIMER_TIDR,
0027 .TIOCP_CFG = OMAP3_TIMER_TIOCP_CFG,
0028 .TISTAT = OMAP3_TIMER_TISTAT,
0029 .TISR = OMAP3_TIMER_TISR,
0030 .TIER = OMAP3_TIMER_TIER,
0031 .TWER = OMAP3_TIMER_TWER,
0032 .TCLR = OMAP3_TIMER_TCLR,
0033 .TCRR = OMAP3_TIMER_TCRR,
0034 .TLDR = OMAP3_TIMER_TLDR,
0035 .TTGR = OMAP3_TIMER_TTGR,
0036 .TWPS = OMAP3_TIMER_TWPS,
0037 .TMAR = OMAP3_TIMER_TMAR,
0038 .TCAR1 = OMAP3_TIMER_TCAR1,
0039 .TSICR = OMAP3_TIMER_TSICR,
0040 .TCAR2 = OMAP3_TIMER_TCAR2,
0041 .TPIR = OMAP3_TIMER_TPIR,
0042 .TNIR = OMAP3_TIMER_TNIR,
0043 .TCVR = OMAP3_TIMER_TCVR,
0044 .TOCR = OMAP3_TIMER_TOCR,
0045 .TOWR = OMAP3_TIMER_TOWR,
0046 };
0047
0048 #if IS_AM335X
0049
0050 static omap_timer_registers_t regs_v2 = {
0051 .TIDR = AM335X_TIMER_TIDR,
0052 .TIOCP_CFG = AM335X_TIMER_TIOCP_CFG,
0053 .TISTAT = AM335X_TIMER_IRQSTATUS_RAW,
0054 .TISR = AM335X_TIMER_IRQSTATUS,
0055 .TIER = AM335X_TIMER_IRQENABLE_SET,
0056 .TWER = AM335X_TIMER_IRQWAKEEN,
0057 .TCLR = AM335X_TIMER_TCLR,
0058 .TCRR = AM335X_TIMER_TCRR,
0059 .TLDR = AM335X_TIMER_TLDR,
0060 .TTGR = AM335X_TIMER_TTGR,
0061 .TWPS = AM335X_TIMER_TWPS,
0062 .TMAR = AM335X_TIMER_TMAR,
0063 .TCAR1 = AM335X_TIMER_TCAR1,
0064 .TSICR = AM335X_TIMER_TSICR,
0065 .TCAR2 = AM335X_TIMER_TCAR2,
0066 .TPIR = -1,
0067 .TNIR = -1,
0068 .TCVR = -1,
0069 .TOCR = -1,
0070 .TOWR = -1
0071 };
0072 #endif
0073
0074
0075
0076
0077
0078 #if IS_DM3730
0079
0080 static omap_timer_t dm37xx_timer = {
0081 .base = OMAP3_GPTIMER1_BASE,
0082 .irq_nr = OMAP3_GPT1_IRQ,
0083 .regs = ®s_v1
0084 };
0085
0086
0087 static omap_timer_t dm37xx_fr_timer = {
0088 .base = OMAP3_GPTIMER10_BASE,
0089 .irq_nr = OMAP3_GPT10_IRQ,
0090 .regs = ®s_v1
0091 };
0092
0093 static struct omap_timer *fr_timer = &dm37xx_fr_timer;
0094 static struct omap_timer *timer = &dm37xx_timer;
0095
0096 #endif
0097
0098 #if IS_AM335X
0099
0100
0101 static omap_timer_t am335x_timer = {
0102 .base = AM335X_DMTIMER1_1MS_BASE,
0103 .irq_nr = AM335X_INT_TINT1_1MS,
0104 .regs = ®s_v1
0105 };
0106
0107
0108 static omap_timer_t am335x_fr_timer = {
0109 .base = AM335X_DMTIMER7_BASE,
0110 .irq_nr = AM335X_INT_TINT7,
0111 .regs = ®s_v2
0112 };
0113
0114 static struct omap_timer *fr_timer = &am335x_fr_timer;
0115 static struct omap_timer *timer = &am335x_timer;
0116
0117 #endif
0118
0119 #if IS_AM335X
0120 #define FRCLOCK_HZ (16*1500000)
0121 #endif
0122
0123 #if IS_DM3730
0124 #define FRCLOCK_HZ (8*1625000)
0125 #endif
0126
0127 #ifndef FRCLOCK_HZ
0128 #error expected IS_AM335X or IS_DM3730 to be defined.
0129 #endif
0130
0131 static void
0132 omap3_frclock_init(void)
0133 {
0134 uint32_t tisr;
0135
0136 #if IS_DM3730
0137
0138 mmio_clear(fr_timer->base + fr_timer->regs->TCLR,
0139 OMAP3_TCLR_ST);
0140
0141
0142 mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10);
0143 #endif
0144
0145 #if IS_AM335X
0146
0147 set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,
0148 CM_MODULEMODE_DISABLED);
0149 while ((mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST)
0150 != CM_CLKCTRL_IDLEST_DISABLE);
0151
0152 set32(CLKSEL_TIMER7_CLK, CLKSEL_TIMER7_CLK_SEL_MASK,
0153 CLKSEL_TIMER7_CLK_SEL_SEL2);
0154 while ((read32(CLKSEL_TIMER7_CLK) & CLKSEL_TIMER7_CLK_SEL_MASK)
0155 != CLKSEL_TIMER7_CLK_SEL_SEL2);
0156
0157
0158 set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,
0159 CM_MODULEMODE_ENABLE);
0160 while ((mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST)
0161 != CM_CLKCTRL_IDLEST_FUNC);
0162
0163
0164 mmio_clear(fr_timer->base + fr_timer->regs->TCLR,
0165 OMAP3_TCLR_ST);
0166 #endif
0167
0168
0169 mmio_write(fr_timer->base + fr_timer->regs->TLDR, 0x0);
0170 mmio_write(fr_timer->base + fr_timer->regs->TCRR, 0x0);
0171
0172
0173 tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
0174 OMAP3_TISR_TCAR_IT_FLAG;
0175
0176 mmio_write(fr_timer->base + fr_timer->regs->TISR, tisr);
0177 mmio_write(fr_timer->base + fr_timer->regs->TIER,
0178 OMAP3_TIER_OVF_IT_ENA);
0179
0180
0181 mmio_set(fr_timer->base + fr_timer->regs->TCLR,
0182 OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST);
0183 }
0184
0185 static uint32_t
0186 beagle_clock_get_timecount(struct timecounter *tc)
0187 {
0188 return mmio_read(fr_timer->base + fr_timer->regs->TCRR);
0189 }
0190
0191 static void
0192 beagle_clock_initialize(void)
0193 {
0194 uint32_t freq = 1000000UL/rtems_configuration_get_microseconds_per_tick();
0195
0196
0197 uint32_t tisr;
0198 #if IS_DM3730
0199
0200 mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
0201
0202
0203 mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1);
0204 #endif
0205
0206 #if IS_AM335X
0207
0208 set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,
0209 CM_MODULEMODE_DISABLED);
0210 while ((mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST)
0211 != CM_CLKCTRL_IDLEST_DISABLE);
0212
0213 set32(CLKSEL_TIMER1MS_CLK, CLKSEL_TIMER1MS_CLK_SEL_MASK,
0214 CLKSEL_TIMER1MS_CLK_SEL_SEL2);
0215 while ((read32(CLKSEL_TIMER1MS_CLK) &
0216 CLKSEL_TIMER1MS_CLK_SEL_MASK) !=
0217 CLKSEL_TIMER1MS_CLK_SEL_SEL2);
0218
0219
0220 set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,
0221 CM_MODULEMODE_ENABLE);
0222 while ((mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST)
0223 != CM_CLKCTRL_IDLEST_FUNC);
0224
0225
0226 mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
0227 #endif
0228
0229
0230 mmio_write(timer->base + timer->regs->TPIR, 232000);
0231 mmio_write(timer->base + timer->regs->TNIR, -768000);
0232 mmio_write(timer->base + timer->regs->TLDR,
0233 0xffffffff - (32768 / freq) + 1);
0234 mmio_write(timer->base + timer->regs->TCRR,
0235 0xffffffff - (32768 / freq) + 1);
0236
0237
0238 tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
0239 OMAP3_TISR_TCAR_IT_FLAG;
0240
0241 mmio_write(timer->base + timer->regs->TISR, tisr);
0242 mmio_write(timer->base + timer->regs->TIER, OMAP3_TIER_OVF_IT_ENA);
0243
0244
0245 mmio_set(timer->base + timer->regs->TCLR,
0246 OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST);
0247
0248 omap3_frclock_init();
0249
0250 #if IS_AM335X
0251
0252 mmio_write(AM335X_WDT_BASE+AM335X_WDT_WSPR, 0xAAAA);
0253 while(mmio_read(AM335X_WDT_BASE+AM335X_WDT_WWPS) != 0) ;
0254 mmio_write(AM335X_WDT_BASE+AM335X_WDT_WSPR, 0x5555);
0255 while(mmio_read(AM335X_WDT_BASE+AM335X_WDT_WWPS) != 0) ;
0256 #endif
0257
0258 \
0259 beagle_clock_tc.tc_get_timecount = beagle_clock_get_timecount;
0260 beagle_clock_tc.tc_counter_mask = 0xffffffff;
0261 beagle_clock_tc.tc_frequency = FRCLOCK_HZ;
0262 beagle_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
0263 rtems_timecounter_install(&beagle_clock_tc);
0264 }
0265
0266 static void beagle_clock_at_tick(void)
0267 {
0268 mmio_write(timer->base + timer->regs->TISR,
0269 OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
0270 OMAP3_TISR_TCAR_IT_FLAG);
0271 }
0272
0273 static rtems_interrupt_handler clock_isr = NULL;
0274
0275 static void beagle_clock_handler_install(rtems_interrupt_handler isr)
0276 {
0277 rtems_status_code sc = RTEMS_SUCCESSFUL;
0278
0279 sc = rtems_interrupt_handler_install(
0280 timer->irq_nr,
0281 "Clock",
0282 RTEMS_INTERRUPT_UNIQUE,
0283 isr,
0284 NULL
0285 );
0286
0287 if (sc != RTEMS_SUCCESSFUL) {
0288 rtems_fatal_error_occurred(0xdeadbeef);
0289 }
0290 clock_isr = isr;
0291 }
0292
0293 #define Clock_driver_support_at_tick(arg) beagle_clock_at_tick()
0294 #define Clock_driver_support_initialize_hardware() beagle_clock_initialize()
0295 #define Clock_driver_support_install_isr(isr) \
0296 beagle_clock_handler_install(isr)
0297
0298
0299 #include "../../shared/dev/clock/clockimpl.h"